Skip to content
This repository was archived by the owner on Dec 7, 2019. It is now read-only.

Commit d200b1c

Browse files
jonas-m-yunikkk
authored andcommitted
Adding support for Android Test Orchestrator (#157)
1 parent b0c12ea commit d200b1c

File tree

5 files changed

+56
-9
lines changed

5 files changed

+56
-9
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,13 @@ Composer shipped as jar, to run it you need JVM 1.8+: `java -jar composer-latest
119119
* Default: `true`.
120120
* `False` may be applicable when you run tests conditionally(via annotation/package filters) and empty suite is a valid outcome.
121121
* Example: `--fail-if-no-tests false`
122+
* `--with-orchestrator`
123+
* Either `true` or `false` to enable/disable running tests via Android Test Orchestrator.
124+
* Default: `false`.
125+
* When enabled - minimizes shared state and isolates test crashes.
126+
* Requires test orchestrator & test services APKs to be installed on device before executing.
127+
* More info: https://developer.android.com/training/testing/junit-runner#using-android-test-orchestrator
128+
* Example: `--with-orchestrator true`
122129

123130
##### Example
124131

@@ -138,7 +145,8 @@ java -jar composer-latest-version.jar \
138145
--output-directory artifacts/composer-output \
139146
--instrumentation-arguments key1 value1 key2 value2 \
140147
--verbose-output false \
141-
--keep-output-on-exit false
148+
--keep-output-on-exit false \
149+
--with-orchestrator false
142150
```
143151

144152
### Download

composer/src/main/kotlin/com/gojuno/composer/Args.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,15 @@ data class Args(
106106
description = "Either `true` or `false` to enable/disable error on empty test suite. True by default.",
107107
order = 11
108108
)
109-
var failIfNoTests: Boolean = true
109+
var failIfNoTests: Boolean = true,
110+
111+
@Parameter(
112+
names = arrayOf("--with-orchestrator"),
113+
required = false,
114+
description = "Either `true` or `false` to enable/disable running tests via Android Test Orchestrator. False by default.",
115+
order = 12
116+
)
117+
var runWithOrchestrator: Boolean = false
110118
)
111119

112120
// No way to share array both for runtime and annotation without reflection.

composer/src/main/kotlin/com/gojuno/composer/Main.kt

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,21 +118,36 @@ private fun runAllTests(args: Args, testPackage: TestPackage.Valid, testRunner:
118118
.subscribeOn(Schedulers.io())
119119
.toList()
120120
.flatMap {
121+
val targetInstrumentation: List<Pair<String, String>>
122+
val testPackageName: String
123+
val testRunnerClass: String
124+
125+
if (args.runWithOrchestrator) {
126+
targetInstrumentation = listOf("targetInstrumentation" to "${testPackage.value}/${testRunner.value}")
127+
testPackageName = "android.support.test.orchestrator"
128+
testRunnerClass = "android.support.test.orchestrator.AndroidTestOrchestrator"
129+
} else {
130+
targetInstrumentation = emptyList()
131+
testPackageName = testPackage.value
132+
testRunnerClass = testRunner.value
133+
}
134+
121135
val instrumentationArguments =
122136
buildShardArguments(
123137
shardingOn = args.shard,
124138
shardIndex = index,
125139
devices = connectedAdbDevices.size
126-
) + args.instrumentationArguments.pairArguments()
140+
) + args.instrumentationArguments.pairArguments() + targetInstrumentation
127141

128142
device
129143
.runTests(
130-
testPackageName = testPackage.value,
131-
testRunnerClass = testRunner.value,
144+
testPackageName = testPackageName,
145+
testRunnerClass = testRunnerClass,
132146
instrumentationArguments = instrumentationArguments.formatInstrumentationArguments(),
133147
outputDir = File(args.outputDirectory),
134148
verboseOutput = args.verboseOutput,
135-
keepOutput = args.keepOutputOnExit
149+
keepOutput = args.keepOutputOnExit,
150+
useTestServices = args.runWithOrchestrator
136151
)
137152
.flatMap { adbDeviceTestRun ->
138153
writeJunit4Report(

composer/src/main/kotlin/com/gojuno/composer/TestRun.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,22 @@ fun AdbDevice.runTests(
4444
instrumentationArguments: String,
4545
outputDir: File,
4646
verboseOutput: Boolean,
47-
keepOutput: Boolean
47+
keepOutput: Boolean,
48+
useTestServices: Boolean
4849
): Single<AdbDeviceTestRun> {
4950

5051
val adbDevice = this
5152
val logsDir = File(File(outputDir, "logs"), adbDevice.id)
5253
val instrumentationOutputFile = File(logsDir, "instrumentation.output")
54+
val commandPrefix = if (useTestServices) {
55+
"CLASSPATH=$(pm path android.support.test.services) app_process / android.support.test.services.shellexecutor.ShellMain "
56+
} else ""
5357

5458
val runTests = process(
5559
commandAndArgs = listOf(
5660
adb,
5761
"-s", adbDevice.id,
58-
"shell", "am instrument -w -r $instrumentationArguments $testPackageName/$testRunnerClass"
62+
"shell", "${commandPrefix}am instrument -w -r $instrumentationArguments $testPackageName/$testRunnerClass"
5963
),
6064
timeout = null,
6165
redirectOutputTo = instrumentationOutputFile,

composer/src/test/kotlin/com/gojuno/composer/ArgsSpec.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ class ArgsSpec : Spek({
3030
devices = emptyList(),
3131
devicePattern = "",
3232
installTimeoutSeconds = 120,
33-
failIfNoTests = true
33+
failIfNoTests = true,
34+
runWithOrchestrator = false
3435
))
3536
}
3637
}
@@ -193,4 +194,15 @@ class ArgsSpec : Spek({
193194
}
194195
}
195196
}
197+
198+
context("parse args with --with-orchestrator") {
199+
200+
val args by memoized {
201+
parseArgs(rawArgsWithOnlyRequiredFields + "--with-orchestrator")
202+
}
203+
204+
it("parses --with-orchestrator correctly") {
205+
assertThat(args.runWithOrchestrator).isEqualTo(true)
206+
}
207+
}
196208
})

0 commit comments

Comments
 (0)