Firebase Test Lab は、Google のデータセンターに置かれた実機と仮想端末でアプリを走らせ、手元に無い機種でしか出ない不具合を拾う仕組みです。始めるだけなら APK を1つ投げれば終わります。効いてくるのはその先で、どのテストを実機へ載せ、どこから先を仮想端末とローカルへ逃がすかという線引きのほう。実機は1台1時間あたり5ドル、仮想端末は1ドルで、分単位の切り上げで積み上がります。この記事では4種類のテストの守備範囲、課金の数え方、gcloud からの実行、CI への組み込み、結果の読み方を、2026年8月時点の実測値で扱います。
まとめ:どのテストを実機へ載せるかを分単位の課金から決める
先に決めるのは端末の割り当てです。仮想端末は1台1時間あたり1ドル、実機は5ドルで5倍の開きがあり、課金は分単位の切り上げ。22秒で終わったテストも1分として計上されます。機種依存やセンサー、実際の描画性能に関わるものだけを実機へ載せ、ロジックの回帰は仮想端末とローカルへ寄せる。この配分が月額をほぼ決めてしまいます。
次に上限です。1回のテストの実行時間は実機で45分、仮想端末で60分が上限。テストスイートがこれを超える規模なら、分割して並列に流す設計が最初から要ります。ただし分割はシャードごとにアプリ起動のオーバーヘッドが乗るため、総時間は縮んでも総額は増える場合がある。時間と金額のどちらを削りたいのかを先に決めておくところです。
最後に結果の置き場所。詳細結果は90日で消えます。受託開発では検収の証跡として残したい場面が出てくるため、自前の Cloud Storage バケットへ出力先を移すか、CI 側のアーティファクトへ写しを取るかを、テストを流し始める前に決めておくと後戻りが起きません。
Test Labが引き受ける4種類のテストと2系統の端末という前提
まず守備範囲です。Test Lab は「テストを書く仕組み」ではなく「書いたテストを他人の端末群で走らせる仕組み」で、種類ごとに対応する OS が違うところが最初の分かれ目になります。
RoboテストはAndroid専用でテストコードなしにUIを踏破する
Robo テストは、アプリの UI 構造を解析して画面を自動で辿り、タップや入力を機械的に試す方式です。事前のテストコードが要らないため、APK を上げるだけで結果が返ってきます。同じ端末構成・同じ設定なら毎回同じ順序で同じ操作を再現するので、変更前後の比較にも使えるところ。
出力されるのはログ、注釈の付いたスクリーンショット、それをつないだ動画、そして画面をノード・操作をエッジとして描いたクロールグラフです。どこまで到達できたかが一目で分かります。ただし標準の Android UI ウィジェットを使っていない画面では、Robo は Monkey Actions というランダムなタップへ退避する仕様。ゲームや独自描画の画面では踏破率が落ちる、と見ておくのが実際に近い。
ログイン画面のように入力が必須の関門は、Robo ディレクティブで特定のフィールドへ値を入れる指定を渡すか、操作を記録した Robo スクリプトを添えて越えさせます。クリック対象に指定できる要素は1つまでなので、複数ステップの導線はスクリプト側で持たせる形。
InstrumentationはEspressoとUI Automatorに絞られる
自分で書いたテストを流すなら Instrumentation テストです。対応フレームワークは Espresso と UI Automator で、Robotium はすでに対象から外れています。手元の connectedAndroidTest がそのまま動く形なので、既存の UI テスト資産があるチームはここが本線。
Android Test Orchestrator を有効にすると、テストは1件ずつ独立したインスタンスで実行されます。1件のクラッシュが後続を巻き込まず、テスト間で状態も共有されない一方、起動のやり直しが毎回入るぶん実行時間は伸びる。伸びた時間はクォータと課金、そして端末のタイムアウト上限に効いてきます。前提として AndroidJUnitRunner は v1.1 以上が要ります。
不安定なテストへの対処としては、失敗したテストを再実行する指定があり、上限は10回、既定は0回です。ただし再実行はフレークを隠す方向にも働きます。E2Eテストのベストプラクティスで扱っている待機と分離の設計を先に整えたうえで、再実行は2回程度の保険に留めるのが扱いやすい線になります。
XCTestとGame Loopが担う範囲と端末2系統の選び分け
iOS は XCTest、ゲームのように UI 操作の自動化が噛み合わない場面は Game Loop テストが受け持ちます。Game Loop は iOS と Android の両方に対応していて、アプリ側にループを実装しておき、それを Test Lab が走らせる形。この2つは Robo のような自動探索ではなく、こちらが定義した筋書きを実行する仕組みです。
| テスト種別 | 対応OS | テストコード |
|---|---|---|
| Robo | Android | 不要 |
| Instrumentation | Android | Espresso等が必要 |
| XCTest | iOS | 必要 |
| Game Loop | iOS・Android | ループの実装が必要 |
端末は2系統です。Google のデータセンターに置かれた実機と、Arm ホスト上で動く仮想 Android 端末。iOS 側に仮想端末の選択肢は無く、すべて実機での実行になります。ここが費用の話に直結します。
課金は分単位の切り上げで実機と仮想端末のあいだに5倍の開きが出る
ここが設計の中心です。無償枠の数え方はプランで変わり、超えた先の単価は端末の種類で5倍違います。
SparkとBlazeでは無償枠の数え方がテスト数と分数で変わる
Spark プランは1日あたり仮想端末10テスト・実機5テストで、時間としては仮想60分・実機30分まで。Blaze プランには回数の枠が無く、1日あたり仮想60分・実機30分までが無償で、そこから先が従量課金という形になります。
| 区分 | Sparkプラン | Blazeプラン |
|---|---|---|
| 仮想端末の無償枠 | 1日10テスト・60分 | 1日60分 |
| 実機の無償枠 | 1日5テスト・30分 | 1日30分 |
| 仮想端末の超過単価 | 枠のみ | 1台1時間1ドル |
| 実機の超過単価 | 枠のみ | 1台1時間5ドル |
| 課金の丸め | 枠のみ | 分単位で切り上げ |
丸めの効き方は具体的です。22秒のテストは1分、75秒のテストは2分として計上されます。短いテストを大量に並べる構成だと、実時間の合計より請求が膨らむ。逆に、インストールと結果収集にかかる時間は課金されないため、1回のテストで複数のケースをまとめて流すほど効率は上がります。Firebaseの料金体系と無料枠の全体像と突き合わせて見積もりへ載せてください。
実行時間の上限は実機45分・仮想60分という枠に収まっている
1回のテストが走り続けられる長さには上限があります。実機は45分、仮想端末は60分。タイムアウトの指定はこの範囲でしか効きません。手元では1時間かかっている回帰スイートを、そのまま実機へ持ち込むと打ち切られます。
対処は2つで、テストを分割して並列に流すか、実機で流す対象をそもそも絞るか。前者なら、シャードあたり2件から10件のテストケースという目安が公式に示されています。分割しすぎるとアプリ起動のオーバーヘッドが端末台数ぶん乗り、時間は縮んでも金額が増える方向へ振れます。
分割実行とOrchestratorは時間を削る一方で総額を押し上げる
分割実行と Orchestrator は、どちらも「1台あたりの実行時間」を増やす方向の機能だと捉えておくと判断を誤りません。Orchestrator は独立実行のぶん起動が増え、分割はシャードの数だけ起動が増える。実機で両方を有効にすると、5ドルという単価に対して分単位の切り上げが何度も掛かります。
実務では、Orchestrator は状態の混線が起きているスイートに限って入れ、分割は45分の上限に当たったときの手段として使います。
gcloudからの実行は端末の一覧を確定させてから組み立てる
コンソールからの実行は入口としては速いものの、繰り返すなら gcloud CLI に寄せたほうが再現性が出ます。なお Test Lab を叩くのは gcloud であって、デプロイに使う firebase-tools とは別系統のコマンドです。認証まわりの運用はFirebase CLIの認証とデプロイ運用で扱っている整理と合わせて、どちらの資格情報で何を動かすかを分けておいてください。
modelsとversionsの一覧で存在する構成だけを端末指定に渡す
最初にやることは端末の棚卸しです。存在しない組み合わせを指定すると、テストは走らずに構成の不整合として弾かれます。
gcloud firebase test android models list
gcloud firebase test android versions list
gcloud firebase test android locales list
取得したモデル ID と API レベルを踏まえて、テストを組み立てます。端末指定は model・version・locale・orientation の4次元で、複数の端末へ同時に流すなら指定を並べる形です。
gcloud firebase test android run \
--type instrumentation \
--app app-debug.apk \
--test app-debug-androidTest.apk \
--device model=MODEL_ID,version=API_LEVEL,locale=ja,orientation=portrait \
--timeout 20m \
--use-orchestrator \
--num-flaky-test-attempts 2
結果の出力先を自前のバケットへ変えるなら結果バケットの指定を足します。同時にディレクトリ名も渡せますが、こちらはテストマトリックスごとに一意である必要がある。ビルド番号やコミットハッシュを混ぜた名前にしておくのが定石です。
Roboの既定タイムアウトはコンソール300秒でgcloudは900秒
Robo テストで見落としやすいのが既定値の差です。Firebase コンソールと Android Studio からの実行は300秒、gcloud からの実行は900秒が既定。同じアプリを同じ端末で流しても、経路が違えば踏破する範囲が変わります。
公式が挙げている目安は、多くのアプリで120秒以上、中程度に複雑なアプリで300秒。ここを短く切ると浅い階層までで打ち切られ、逆に900秒のまま実機で回すと1回15分ぶんの課金が乗ります。Robo は時間を渡した分だけ潜る性質なので、タイムアウトは踏破させたい画面数から逆算して明示的に指定するのが確実です。
iOSはビルド成果物のzipとXcodeの版指定で組み立てが決まる
iOS 側は渡すものが違います。ビルド出力の Products にある Debug-iphoneos ディレクトリと .xctestrun ファイルを zip で固め、それをテストとして渡す形。Xcode の版はフラグで固定できるため、ビルドに使った版と揃えておくと互換性の事故が減ります。利用できるモデル・バージョン・ロケール・Xcode の版は、ディメンションの一覧コマンドで確認できます。
プッシュ通知や VPN を含むテストには特別なエンタイトルメントの指定が要りますが、これを付けると Test Lab 側で再署名が入り、バンドル ID が変わります。App Group に依存したテストはこの時点で失敗する。iOS で実機テストの範囲を決めるときは、この制約を先に確認しておくところです。
CIへ組み込むときに決めておく認証の寄せ先と終了コードの取り扱い
手元から流している間は問題になりませんが、CI へ載せた途端に効くのが認証と終了コードの扱いです。
サービスアカウントへ寄せてcaptchaで止まる経路を先に断つ
個人アカウントの資格情報のまま CI へ持ち込むと、スパム判定や captcha の表示でビルドが止まります。サービスアカウントはこれらの対象外なので、CI からの実行はそちらへ寄せてください。手順は Editor ロールのサービスアカウントを作り、gcloud で有効化し、Google Cloud Testing API と Cloud Tool Results API を有効にする3手です。
gcloud auth activate-service-account \
--key-file=service-account.json
gcloud config set project PROJECT_ID
鍵ファイルは CI のシークレットへ置き、ジョブの中で書き出して使い切る形にします。テスト結果のログや動画を後続のジョブへ渡すなら、GitHub Actionsのアーティファクトの受け渡し設計で扱っている保持期間と同名不可の制約に合わせて置き場所を決めておくと、後から探しに行けます。
終了コード10と20を分けないとCIの赤が原因不明のまま残る
gcloud の終了コードは失敗の種類まで区別しています。ここを一括で「失敗」として扱うと、アプリの不具合なのか基盤側の一時障害なのかが CI のログから読み取れなくなります。
| 終了コード | 意味 | CIでの扱い |
|---|---|---|
| 0 | 全件が成功 | 通過 |
| 1 | 一般的な失敗 | 指定内容を確認 |
| 10 | テストケースの失敗 | アプリ側を調査 |
| 18 | 端末構成の不整合 | 端末指定を修正 |
| 19 | マトリックスの中止 | 再実行の対象 |
| 20 | テスト基盤側のエラー | 再実行の対象 |
実務で分けたいのは10と20です。10ならアプリのコードかテストの問題なので開発側へ返す。20は Test Lab 側の障害なので、そのまま再実行のキューへ回します。18が出るのはたいてい端末指定の書き間違いで、モデル ID と API レベルの組み合わせが存在しないときに返ってくるコードです。
再実行の上限は10回でフレークを隠してしまう線引きを先に決める
失敗したテストの再実行は最大10回まで指定できますが、既定は0回です。回数を上げるほど CI は緑になりやすくなり、同時に不安定なテストが見えなくなります。回数を上げる前に、その失敗が端末側のタイミングによるものか、テストの待機設計によるものかを分けてください。
結果の読み方は90日という保持期間から逆算して先に決めておく
テストを流したあと、どこに何が残るのか。把握しないまま運用へ入ると、検収の場面で証跡が出せなくなります。
テストマトリックスはデバイスとテスト実行の掛け算として数える
Test Lab の結果はテストマトリックスという単位で構成されます。デバイスとテスト実行の掛け算で、端末を3台指定すれば3つの実行が並ぶ形。実行ごとに成功・失敗・判定不能・スキップの結果が付き、選んだ API レベルと端末構成が噛み合わない場合はスキップとして返ります。
端末を1台増やすことは、テスト時間をもう1本増やすことと同じです。網羅したい機種の数と1回あたりの実行時間の積が、そのまま請求額の骨格になります。
コンソールで見えるログと動画と性能指標とアクティビティマップ
Firebase コンソールに出るのは、ログ・スクリーンショット・動画に加えて、起動時間、CPU、メモリ、ネットワーク、フレームレートといった性能指標です。Robo テストなら、どの画面を辿ったかを示すアクティビティマップも付きます。Android アクセシビリティスキャナの結果も同じ画面から確認できるところ。
実機テストで拾えるのは、あくまでテストを流した範囲の挙動です。本番のユーザー環境で起きるクラッシュは別系統で集める必要があり、その役割はFirebase Crashlyticsによるクラッシュ収集が受け持ちます。テスト版をテスターへ配る経路そのものはFirebase App Distributionの配信設計の領分で、自然言語のテストケースを Test Lab の端末で走らせる App Testing agent もそちらの扱いです。
90日を越えて残すなら結果の出力先を自前のバケットへ切り替える
詳細な結果は、テストを流してから90日で参照できなくなります。既定では Test Lab が用意する Cloud Storage バケットに置かれる形。90日を超えて保持したい場合は、結果バケットの指定で自前のバケットへ出力し、そのバケットを持つプロジェクトで課金を有効にしたうえで、ライフサイクル設定を自分で決めます。
受託開発では、検収の材料としてテスト結果を引き渡す場面が出てきます。90日というのは、要件定義から検収まで半年かかる案件では足りない長さ。プロジェクトの初期に自前バケットへ切り替えておくか、CI のアーティファクトへ写しを残す運用にしておくのが安全側です。
受託開発でTest Labを主線に据える条件と見送る場面の線引き
ここまでの制約を案件ごとの判断へ落とします。Test Lab はテスト戦略の全体を置き換えるものではなく、実機の調達と管理を外へ出す手段だと捉えると線が引きやすくなります。
Test Labをテストの主線に据えてよい受託案件の3つの条件
第一に、機種依存の不具合が実際に発生している案件。OEM ごとの挙動差やメーカー独自のカスタマイズに起因する不具合は、社内の数台では再現しません。ここは実機を借りるより Test Lab のほうが早く、安く済みます。
第二に、Android が主戦場で Espresso のテスト資産がある、あるいは Robo の自動探索で受け入れ確認が足りる案件。Instrumentation も Robo も Android 専用なので、Android 比率が高いほど投資に見合う結果が返ってきます。
第三に、CI の実行時間と課金を分単位で見積もれる体制がある案件。1日あたりの実行回数、端末台数、1回の実行時間を掛けて月額を出せるなら、無償枠30分を超えた先も読めます。逆にここが読めないまま常時実行へ載せると、実機5ドルの単価が静かに積み上がっていく。
実機テストをTest Lab以外へ寄せたい4つの実務上の場面
1つ目は iOS 単独の案件で XCTest を厚く回す場合です。iOS には仮想端末の選択肢が無く、すべて5ドルの実機になります。zip の作成と再署名の制約も乗るため、Xcode Cloud や社内の実機を含めた構成と比較したうえで決めたほうがいい領域。
2つ目は、ローカルで再現できる範囲の検証です。Firestore のルールや Functions の挙動確認は、Local Emulator Suiteによるローカル再現のほうが速く、費用も掛かりません。実機へ載せる価値があるのは、端末やハードウェアの差が出る部分だけ。
3つ目は、App Group やプッシュ通知に強く依存した iOS の検証です。再署名でバンドル ID が変わる制約に当たるため、そのままでは通りません。
4つ目は、テスト結果を長期に保管することが契約上の要件になっている案件。90日という既定の保持期間に対して、自前バケットの用意と課金の有効化が前提条件として乗ってきます。要件として明示されているなら、テストを流し始める前にインフラ側の設計へ含めておきます。
保守フェーズへ引き渡す前に決めておきたい課金と保管の3つの取り決め
保守フェーズへ渡す前に、3点を文書で固めておくと引き継ぎが揉めません。1つ目は課金の持ち主で、Blaze プランの請求先と1日あたりの実行上限の目安。2つ目は結果の保管先で、自前バケットへ出すのか90日で消える前提で証跡を別に取るのか。3つ目は、どの端末構成を回帰の対象として維持するかという一覧です。
アプリの受託開発で、この種のテスト基盤をプロジェクトの初期から設計へ組み込みたい場合は、iOS・Android双方に対応するスマホアプリ開発のなかでご相談ください。端末の網羅範囲と月額の見積もりを、案件の要件に合わせて詰められます。
よくある質問
Firebase Test Labは無料で使えますか?
枠の範囲であれば費用は掛かりません。Spark プランは1日に仮想端末10テスト・実機5テストまで、時間としては仮想60分・実機30分まで。Blaze プランは回数の枠が無く、1日あたり仮想60分・実機30分までが無償で、超過分は仮想端末が1台1時間あたり1ドル、実機が5ドルです。分単位の切り上げで計上される点は見積もりに入れてください。
実機と仮想端末はどちらを選べばよいですか?
端末やハードウェアの差が結果を左右する検証は実機、それ以外は仮想端末という配分が基本です。カメラ、センサー、メーカー独自のカスタマイズ、描画性能に関わる部分は実機でなければ拾えません。一方、画面遷移やロジックの回帰は仮想端末で足ります。単価が5倍違うため、この振り分けが月額をほぼ決めるところ。
Roboテストだけでテストコードは不要になりますか?
クラッシュの検出や到達可能な画面の確認までは、テストコードなしで回せます。ただし Robo が確かめるのは落ちずに辿れるかどうかであって、業務ロジックの正しさは判定しません。標準の UI ウィジェットを使わない画面では踏破率も落ちます。受け入れ条件の検証には Espresso や UI Automator による Instrumentation テストの併走が要ります。
iOSでもRoboテストは使えますか?
使えません。Robo テストと Instrumentation テストは Android 専用で、iOS で流せるのは XCTest と Game Loop テストです。iOS 側は仮想端末の提供も無いため、すべて実機での実行になります。iOS を含む案件では、テストコードの整備を前提に見積もりを組んでください。
テスト結果はいつまで見られますか?
詳細な結果は実行から90日間、Cloud Storage バケットに保持され、Firebase コンソールからも参照できます。それを超えて残すには、結果の出力先を自前のバケットへ指定し、そのバケットを持つプロジェクトで課金を有効にしたうえでライフサイクルを設定します。検収の証跡として使う場合は、この切り替えを最初に済ませておくのが安全です。
関連記事
- Firebase App Distributionとは:テスト版ビルドをテスターへ配る側の設計です。
- Firebase Crashlyticsとは:テストで拾えない実利用のクラッシュ収集です。
- Firebase Local Emulator Suiteとは:実機へ載せる前のローカル検証の範囲です。
- Firebase CLIとは:gcloudと分ける資格情報の運用です。
- Firebaseの料金:無料枠とBlaze超過単価の全体像です。
- GitHub Actionsのアーティファクト:テスト結果をCIで持ち回る設計です。
- E2Eテストのベストプラクティス:フレークを減らす待機と分離の設計です。