Marathon Cloud supports native Android testing frameworks and cross-platform solutions. You can run tests written in Espresso, UIAutomator, Kakao, Kaspresso, and Flutter (via Patrol).
Quick start
Section titled “Quick start”marathon-cloud run android \ --api-key $MARATHON_CLOUD_API_KEY \ --application app-debug.apk \ --test-application app-debug-androidTest.apkSupported frameworks
Section titled “Supported frameworks”Marathon Cloud executes standard Android instrumentation tests. The following frameworks are fully supported:
- Espresso: The standard framework for Android UI testing.
- UIAutomator: For cross-app functional UI testing.
- Kakao/Kaspresso: DSL wrappers around Espresso for better readability and stability.
- Cucumber: For behavior-driven development.
- Flutter (Patrol): For testing Flutter applications with native features.
Build your test APKs
Section titled “Build your test APKs”You must provide two APK files: the application under test and the instrumentation test APK.
-
Open your terminal in the root of your Android project.
-
Run the Gradle assembly tasks for both the app and the test app.
Terminal window ./gradlew :app:assembleDebug :app:assembleDebugAndroidTest -
Locate the generated APKs in the build output directory. Typically, these are found at:
app/build/outputs/apk/debug/app-debug.apkapp/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk
Run tests
Section titled “Run tests”marathon-cloud run android \ --api-key YOUR_API_KEY \ --application path/to/app-debug.apk \ --test-application path/to/app-debug-androidTest.apk \ --os-version 15 \ --system-image google_apisThe examples below omit --api-key; the CLI reads it from MARATHON_CLOUD_API_KEY when the flag is absent.
Device selection
Section titled “Device selection”| Parameter | Description |
|---|---|
--os-version |
Android version: 8, 8.1, 9, 10, 11, 12, 13, 14, 15, 16, 17. |
--system-image |
default, google_apis, or google_apis_playstore. |
--arch |
amd64 (default) or arm64. Pick arm64 when the app ships native libraries without an x86_64 ABI or you want to match production hardware. |
--device |
Device type ID from marathon-cloud devices android. Use watch or tv for those form factors; omit for a phone. See supported devices. |
Not every combination is valid, and the CLI rejects invalid ones before uploading:
- Android
15,16,17requiregoogle_apisorgoogle_apis_playstore. - Android
8to9requiregoogle_apis. watchrequiresgoogle_apisand Android11,13, or15;tvrequiresgoogle_apisand Android10to14.arm64requires Android9or later.defaultimages arearm64only; usegoogle_apisorgoogle_apis_playstoreforamd64.
--flavor is deprecated; only native instrumentation tests are supported and the flag is ignored.
Advanced configuration
Section titled “Advanced configuration”Multi-module and library testing
Section titled “Multi-module and library testing”--application-bundle replaces --application + --test-application for multi-module projects and can be repeated to run several modules in one run. --library-bundle is for library modules that have a test APK but no app APK.
marathon-cloud run android \ --application-bundle app/build/outputs/apk/debug/app-debug.apk,app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk \ --application-bundle feature/build/outputs/apk/debug/feature-debug.apk,feature/build/outputs/apk/androidTest/debug/feature-debug-androidTest.apkmarathon-cloud run android \ --library-bundle mylib/build/outputs/apk/androidTest/debug/mylib-debug-androidTest.apkDevice features and sensors
Section titled “Device features and sensors”Camera emulation requires a google_apis or google_apis_playstore image. --mock-location is a switch and takes no value.
marathon-cloud run android \ --application app-debug.apk \ --test-application app-debug-androidTest.apk \ --os-version 15 \ --system-image google_apis \ --mock-location \ --front-camera emulated \ --back-camera virtualsceneInstrumentation arguments and pulled files
Section titled “Instrumentation arguments and pulled files”--instrumentation-arg is repeatable and passed through to the instrumentation runner. --pull-files copies files off the device after each batch into device-files.tar in the artifacts; the path is relative to the chosen root.
marathon-cloud run android \ --application app-debug.apk \ --test-application app-debug-androidTest.apk \ --code-coverage \ --instrumentation-arg "debug=true" \ --instrumentation-arg "clearPackageData=true" \ --pull-files "EXTERNAL_STORAGE:screenshots" \ --pull-files "APP_DATA:files/reports"ROOT is EXTERNAL_STORAGE (/sdcard) or APP_DATA (the app’s private data directory). Files with the same path from different devices overwrite each other in the archive.
Isolated execution
Section titled “Isolated execution”--isolated puts every test in its own batch so no test shares a batch with another.
Use it to confirm whether a failure depends on tests that ran before it; it makes the run longer and more expensive. See batching.
marathon-cloud run android \ --application app-debug.apk \ --test-application app-debug-androidTest.apk \ --isolatedLimiting parallelism
Section titled “Limiting parallelism”Marathon Cloud sizes the device pool to finish in about 15 minutes, which can mean many devices hitting your backend at once. If your tests share fixtures or your staging backend cannot take the load, cap the pool:
marathon-cloud run android \ --application app-debug.apk \ --test-application app-debug-androidTest.apk \ --concurrency-limit 4Treat this as a stopgap; see limiting concurrency.
Gating CI
Section titled “Gating CI”The command exits 1 if any test fails and 0 otherwise. Add --result-file result.json for a machine-readable summary and --output ./results to download JUnit XML and videos. See exit codes.