Firebase Test Lab: Mobile Testing on Real and Virtual Devices
Firebase Test Lab is Google's cloud-based mobile testing infrastructure. It runs your Android and iOS tests on real and virtual devices hosted by Google, with results available in the Firebase Console or via the gcloud CLI.
For Android developers already in the Firebase ecosystem, Test Lab is the natural first choice for device farm testing. It integrates tightly with Google Play, Android Studio, and Google Cloud Build.
What Firebase Test Lab Provides
Device catalog: Physical devices (200+ Android, select iOS) and virtual devices (Android emulators configured by Google, with various API levels and screen sizes).
Test types:
- Instrumentation tests (Espresso, UIAutomator) — your existing Android test code
- XCTest — your existing iOS test code
- Robo tests — Firebase's crawler that explores your app automatically without test code
- Game Loop tests — for Unity/game apps
Key advantage over DIY emulators: Google manages the infrastructure — device availability, OS updates, and flakiness management. You don't configure emulators; you just specify what you want.
Supported Test Frameworks
| Framework | Platform |
|---|---|
| Espresso | Android |
| UIAutomator 2 | Android |
| XCTest/XCUITest | iOS |
| Robo (automated crawl) | Android |
| Game Loop | Android/iOS |
Running Your First Test
Prerequisites
- Firebase project with Blaze (pay-as-you-go) plan — required for Test Lab
gcloudCLI installed and authenticated- Compiled test APK (or XCTest ZIP for iOS)
Android Instrumentation Test
# Run Espresso tests on physical Samsung Galaxy devices
gcloud firebase test android run \
--type instrumentation \
--app app/build/outputs/apk/debug/app-debug.apk \
--test app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk \
--device model=shiba,version=34,locale=en,orientation=portrait \
--device model=oriole,version=33,locale=en,orientation=portrait \
--timeout 5miOS XCTest
gcloud firebase test ios run \
--test MyApp.zip \
--device model=iphone15pro,version=17.2Robo Test (No Test Code Required)
gcloud firebase test android run \
--type robo \
--app app-debug.apk \
--device model=shiba,version=34 \
--robo-directives username_resource=com.yourapp:id/email_field:testuser@example.com,password_resource=com.yourapp:id/password_field:TestPass123 \
--timeout 3mThe --robo-directives tell Robo how to handle login fields — without this, it can't get past authentication screens.
CI/CD Integration
GitHub Actions
name: Firebase Test Lab
on:
push:
branches: [main, develop]
pull_request:
jobs:
android-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Build debug APKs
run: ./gradlew assembleDebug assembleDebugAndroidTest
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v1
with:
credentials_json: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }}
- name: Set up gcloud
uses: google-github-actions/setup-gcloud@v1
- name: Run Firebase Test Lab
run: |
gcloud firebase test android run \
--project ${{ secrets.FIREBASE_PROJECT_ID }} \
--type instrumentation \
--app app/build/outputs/apk/debug/app-debug.apk \
--test app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk \
--device model=shiba,version=34,locale=en,orientation=portrait \
--device model=cheetah,version=33,locale=en,orientation=portrait \
--results-bucket gs://${{ secrets.FIREBASE_PROJECT_ID }}-test-results \
--results-dir ${{ github.run_id }} \
--timeout 10m
- name: Upload test results
if: always()
uses: actions/upload-artifact@v3
with:
name: firebase-test-results
path: /tmp/test-results/Google Cloud Build
steps:
- name: 'gradle:8-jdk17'
args: ['assembleDebug', 'assembleDebugAndroidTest']
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
args:
- 'firebase'
- 'test'
- 'android'
- 'run'
- '--type=instrumentation'
- '--app=app/build/outputs/apk/debug/app-debug.apk'
- '--test=app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk'
- '--device=model=shiba,version=34'
- '--timeout=10m'Listing Available Devices
# List Android devices
gcloud firebase test android models list
# List iOS devices
gcloud firebase test ios models list
# List Android OS versions
gcloud firebase test android versions list
# Get details on a specific model
gcloud firebase test android models describe shibaSample Android model identifiers: shiba (Pixel 8), oriole (Pixel 6), cheetah (Pixel 7 Pro), redfin (Pixel 5).
Test Matrix Configuration
For comprehensive coverage, define a test matrix:
gcloud firebase test android run \
--type instrumentation \
--app app-debug.apk \
--test app-debug-androidTest.apk \
--device model=shiba,version=34 \
--device model=shiba,version=33 \
--device model=oriole,version=32 \
--device model=samsung_a52sxq,version=33 \
--device model=cactus,version=27 \ # Low-end budget device
--test-targets "class com.yourapp.LoginTest,com.yourapp.CheckoutTest" \
--timeout 15mThe --test-targets filter runs only specific tests — useful for "smoke test" device matrices that run faster.
Understanding Results
After a run, Test Lab provides for each device:
Summary view (Firebase Console):
- Pass/fail per test case per device
- Robo test coverage map (which screens were reached)
Detailed artifacts:
logcat— full Android log output- Video recording — full test execution
- Screenshots — captured on failures
- JUnit XML — for CI result parsing
# Download results via gsutil
gsutil cp -r gs://my-project-test-results/run-123/ ./results/Parsing JUnit Results in CI
- name: Publish Test Results
uses: EnricoMi/publish-unit-test-result-action@v2
if: always()
with:
files: results/**/test_result_*.xmlRobo Test Best Practices
Robo tests are valuable for:
- Regression detection without writing test code
- Exploring new features before tests are written
- Crash detection across the app
Maximize Robo coverage:
gcloud firebase test android run \
--type robo \
--app app-debug.apk \
--device model=shiba,version=34 \
--robo-directives \
username_resource=com.yourapp:id/email:testuser@example.com,\
password_resource=com.yourapp:id/password:TestPass123,\
click_resource=com.yourapp:id/skip_tutorial \
--robo-script robo-script.json \
--timeout 5mThe --robo-script JSON file records a sequence of actions (tap, swipe, type) that Robo executes first before exploring on its own — useful for getting past onboarding flows.
Firebase Test Lab vs. Local Emulators
| Scenario | Firebase Test Lab | Local Emulator |
|---|---|---|
| Final release validation | Better — real devices | Worse |
| Developer iteration | Worse (upload time) | Better (instant) |
| Cost for 5 runs/day | ~$5–15/day | Near zero |
| Parallel device testing | Built-in | Limited by machine |
| CI integration | Native | Requires setup |
Use local emulators during development; Firebase Test Lab for PR checks and release gate.
Pricing
Firebase Test Lab pricing (us-central1):
- Physical devices: ~$5/device-hour
- Virtual devices: ~$1/device-hour
- Spark plan (free tier): 10 virtual device tests/day, 5 physical device tests/day
For most CI pipelines running on PRs + daily release runs, expect $50–200/month depending on test duration and device count.
Firebase Test Lab vs. AWS Device Farm
| Factor | Firebase Test Lab | AWS Device Farm |
|---|---|---|
| Android integration | Excellent (Google) | Good |
| iOS support | Limited models | Broader selection |
| Pricing model | Per hour | Per minute |
| Robo test (no-code) | Native | Not available |
| CI/CD | gcloud CLI | AWS CLI + GitHub Action |
| Existing cloud | GCP teams | AWS teams |
Choose Firebase Test Lab if you're on GCP/Firebase. Choose Device Farm if you're AWS-first or need broader iOS coverage.
Summary
Firebase Test Lab is a solid choice for Android-first teams. The Robo test is unique — free crash detection and screen exploration without writing a single line of test code. Combined with your Espresso test suite, you get both structured test coverage and opportunistic discovery.
Start with the free tier (10 virtual device tests/day), add your Espresso tests, and upgrade to Blaze plan when you need physical devices or higher parallelism.