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

Commit

Permalink
Adding support for Android Test Orchestrator (#157)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonas-m- authored and yunikkk committed Oct 14, 2018
1 parent b0c12ea commit d200b1c
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 9 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ Composer shipped as jar, to run it you need JVM 1.8+: `java -jar composer-latest
* Default: `true`.
* `False` may be applicable when you run tests conditionally(via annotation/package filters) and empty suite is a valid outcome.
* Example: `--fail-if-no-tests false`
* `--with-orchestrator`
* Either `true` or `false` to enable/disable running tests via Android Test Orchestrator.
* Default: `false`.
* When enabled - minimizes shared state and isolates test crashes.
* Requires test orchestrator & test services APKs to be installed on device before executing.
* More info: https://developer.android.com/training/testing/junit-runner#using-android-test-orchestrator
* Example: `--with-orchestrator true`

##### Example

Expand All @@ -138,7 +145,8 @@ java -jar composer-latest-version.jar \
--output-directory artifacts/composer-output \
--instrumentation-arguments key1 value1 key2 value2 \
--verbose-output false \
--keep-output-on-exit false
--keep-output-on-exit false \
--with-orchestrator false
```

### Download
Expand Down
10 changes: 9 additions & 1 deletion composer/src/main/kotlin/com/gojuno/composer/Args.kt
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,15 @@ data class Args(
description = "Either `true` or `false` to enable/disable error on empty test suite. True by default.",
order = 11
)
var failIfNoTests: Boolean = true
var failIfNoTests: Boolean = true,

@Parameter(
names = arrayOf("--with-orchestrator"),
required = false,
description = "Either `true` or `false` to enable/disable running tests via Android Test Orchestrator. False by default.",
order = 12
)
var runWithOrchestrator: Boolean = false
)

// No way to share array both for runtime and annotation without reflection.
Expand Down
23 changes: 19 additions & 4 deletions composer/src/main/kotlin/com/gojuno/composer/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -118,21 +118,36 @@ private fun runAllTests(args: Args, testPackage: TestPackage.Valid, testRunner:
.subscribeOn(Schedulers.io())
.toList()
.flatMap {
val targetInstrumentation: List<Pair<String, String>>
val testPackageName: String
val testRunnerClass: String

if (args.runWithOrchestrator) {
targetInstrumentation = listOf("targetInstrumentation" to "${testPackage.value}/${testRunner.value}")
testPackageName = "android.support.test.orchestrator"
testRunnerClass = "android.support.test.orchestrator.AndroidTestOrchestrator"
} else {
targetInstrumentation = emptyList()
testPackageName = testPackage.value
testRunnerClass = testRunner.value
}

val instrumentationArguments =
buildShardArguments(
shardingOn = args.shard,
shardIndex = index,
devices = connectedAdbDevices.size
) + args.instrumentationArguments.pairArguments()
) + args.instrumentationArguments.pairArguments() + targetInstrumentation

device
.runTests(
testPackageName = testPackage.value,
testRunnerClass = testRunner.value,
testPackageName = testPackageName,
testRunnerClass = testRunnerClass,
instrumentationArguments = instrumentationArguments.formatInstrumentationArguments(),
outputDir = File(args.outputDirectory),
verboseOutput = args.verboseOutput,
keepOutput = args.keepOutputOnExit
keepOutput = args.keepOutputOnExit,
useTestServices = args.runWithOrchestrator
)
.flatMap { adbDeviceTestRun ->
writeJunit4Report(
Expand Down
8 changes: 6 additions & 2 deletions composer/src/main/kotlin/com/gojuno/composer/TestRun.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,22 @@ fun AdbDevice.runTests(
instrumentationArguments: String,
outputDir: File,
verboseOutput: Boolean,
keepOutput: Boolean
keepOutput: Boolean,
useTestServices: Boolean
): Single<AdbDeviceTestRun> {

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

val runTests = process(
commandAndArgs = listOf(
adb,
"-s", adbDevice.id,
"shell", "am instrument -w -r $instrumentationArguments $testPackageName/$testRunnerClass"
"shell", "${commandPrefix}am instrument -w -r $instrumentationArguments $testPackageName/$testRunnerClass"
),
timeout = null,
redirectOutputTo = instrumentationOutputFile,
Expand Down
14 changes: 13 additions & 1 deletion composer/src/test/kotlin/com/gojuno/composer/ArgsSpec.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class ArgsSpec : Spek({
devices = emptyList(),
devicePattern = "",
installTimeoutSeconds = 120,
failIfNoTests = true
failIfNoTests = true,
runWithOrchestrator = false
))
}
}
Expand Down Expand Up @@ -193,4 +194,15 @@ class ArgsSpec : Spek({
}
}
}

context("parse args with --with-orchestrator") {

val args by memoized {
parseArgs(rawArgsWithOnlyRequiredFields + "--with-orchestrator")
}

it("parses --with-orchestrator correctly") {
assertThat(args.runWithOrchestrator).isEqualTo(true)
}
}
})

0 comments on commit d200b1c

Please sign in to comment.