SauceLabs
SauceLabs is a popular cloud device farm, with virtual and real devices on both Android and iOS.
Your Patrol tests are ordinary native tests (Espresso on Android, XCUITest on iOS), so this page only covers what is specific to Patrol. For the config format, device names, sharding options and everything else, follow SauceLabs' Espresso and XCUITest docs.
Prerequisites
- The standard Patrol setup. Unlike BrowserStack and LambdaTest, SauceLabs needs no
farm-specific
testInstrumentationRunner, so keep thepl.leancode.patrol.PatrolJUnitRunneryou already have. - saucectl installed, with
SAUCE_USERNAMEandSAUCE_ACCESS_KEYexported.
Android
Build
patrol build androidPoint a config at the two APKs
The command prints both paths. If you use a flavor, both the directory and the file
name carry it (apk/staging/debug/app-staging-debug.apk).
apiVersion: v1alpha
kind: espresso
sauce:
region: us-west-1
espresso:
app: build/app/outputs/apk/debug/app-debug.apk
testApp: build/app/outputs/apk/androidTest/debug/app-debug-androidTest.apk
suites:
- name: "Android"
devices:
- name: "Google Pixel 9 Pro"Run
saucectl run --config .sauce/android.ymlIf every test executes twice, restrict the suite to the class that build-time test discovery generated:
testOptions:
class:
- com.example.myapp.PatrolGeneratedTestsDiscovery adds that class to your APK rather than replacing the MainActivityTest
host from your setup. Both enumerate your whole Dart suite, and SauceLabs runs every
test class the APK contains. You won't see this under patrol test, which narrows
the class itself.
iOS
Build
patrol build ios --simulator # or --release, for real devicesFor real devices, XCUITest wants .ipa files rather than the .app bundles the
build produces. Pack each one into an .ipa (a zip with the .app inside a
Payload/ directory) and point your config at the results.
Do the Setup for physical iOS devices first. The test runner is a separate app from the one under test, so it needs its own identifier, certificate and profile.
Point a config at the two bundles
apiVersion: v1alpha
kind: xcuitest
sauce:
region: us-west-1
xcuitest:
app: build/ios_integ/Build/Products/Debug-iphonesimulator/Runner.app
testApp: build/ios_integ/Build/Products/Debug-iphonesimulator/RunnerUITests-Runner.app
suites:
- name: "iOS"
simulators:
- name: "iPhone 15 Simulator"
platformVersions:
- "17.0"Run
saucectl run --config .sauce/ios.ymlWhen a test fails, look for the Dart stack trace in the job's xcodebuild.log
asset. The JUnit report truncates the failure message.
Sharding
SauceLabs shards XCUITest by splitting an explicit list of test identifiers
(shard: concurrency with testListFile). To generate that list you need
build-time test discovery. That page
has the one-liner that writes the file, and the caveat that the entry format differs
between simulators and real devices.