To do・In progress・Doneに区分されたカンバンボード
技術解説

テストが緑でも信頼できない理由:環境ドリフトとCIノイズの正体

目次を見る

ブラウザテストがすべてパスしているのに、本番環境で障害が発生する。この状況は「テストの品質が悪い」という話ではなく、「テストが意図した対象を測定できていない」という構造的な問題から生じます。シード記事が指摘する核心は、テストランナーが訪問しているURLと、アプリケーションが実際に実行しているコードパスが一致していない場合があるという点です。

環境ドリフトとは何か

環境ドリフト(Environment Drift)とは、テストが動作する環境と、実際の本番環境の間に生じる設定・データ・依存サービスの乖離を指します。乖離の原因は多岐にわたります。フィーチャーフラグ(Feature Flag)の状態、データベースのシードデータ、依存APIのバージョン、ビルド設定の違いなどが代表的です。

たとえばフィーチャーフラグとは、コードを変更せずに機能のON/OFFを制御する仕組みです。ステージング環境だけで特定のフラグが有効になっていると、同じURLを開いてもコンポーネントツリーが本番と異なる状態になります。ボタンがメニューに移動する、フォームがウィザード形式に変わるといった変化が起き、テストが書かれた画面構造と実際の画面構造がずれます。テストランナーからは「同じページを開いている」ように見えても、アプリケーション内部では別のコードが動いているわけです。

この問題に対処するために有効なのは、テスト実行時にどのフラグが有効だったかをログに記録することです。「staging」というラベルだけでは不十分で、実際のフラグ名・値・評価タイミング(サーバーサイドか、ブラウザ側か)を残す必要があります。障害が再現しない原因の多くは、開発者がローカルで異なるフラグ状態を使って確認しているためです。

エフェメラル環境とAPIモックが引き起こす誤検知

エフェメラル環境(Ephemeral Environment)とは、PRごとに一時的に立ち上がり、マージ後に破棄されるプレビュー用の環境です。デプロイURLが発行された時点で「環境が使える」と判断しがちですが、それはアプリケーションが起動しただけの状態に過ぎません。

実際にテストを正しく実行するには、以下が揃っている必要があります。

  • デプロイされたコミットIDまたはビルド識別子
  • 依存サービスのバージョン
  • データベースのシードデータ(期待するテストデータが投入済みか)
  • キュー・メールサービス・オブジェクトストレージの疎通確認
  • フィーチャーフラグの設定
  • テストアカウントの権限と契約状態

これらを確認する「環境検証フェーズ」をテストスイートの冒頭に挟む構成が推奨されます。40分かかるE2Eスイートを、シードデータが存在しない環境に対して実行しても、得られる情報は「環境が壊れていた」という事実だけです。早期に失敗させることでCI時間の無駄を省けます。

APIモックの問題はさらに深刻です。モックとは、外部APIの代わりに固定のレスポンスを返す差し替えの仕組みです。実際のAPIがステータスフィールドを文字列からネストされたオブジェクトに変更しても、モックが古い構造を返し続ける限りテストは緑のままです。本番では存在しないコードパスを実行して「合格」が出続けます。これは安定したスイートが虚偽の安心感を生む状態で、モックドリフト(Mock Drift)と呼ばれます。

対策の一つは、スキーマ検証の自動化です。たとえばOpenAPI仕様書からモックフィクスチャを自動生成するツール(Prism、Mockoonなど)を使うと、APIの仕様変更がモックに追従します。全テストをリアルAPIに向けるのはコストが高いため、コアなフローだけを実APIで週次実行するなどのハイブリッド戦略が現実的です。

# Prismを使ってOpenAPI仕様からモックサーバーを起動する例
npx @stoplight/prism-cli mock openapi.yaml --port 4010

CI環境特有のノイズをどう扱うか

フレーキーテスト(Flaky Test)とは、同じコードに対してパスと失敗が非決定論的に繰り返されるテストのことです。Reactのバージョンアップ後に描画タイミングが変わり、要素取得のタイムアウトが断続的に発生するケースが典型的です。ユーザー向けの動作は変わっていないため、コードレビューでは検出されません。

CI環境はローカルとCPU・メモリ・ネットワーク帯域が異なります。ミニファイされたビルド(コードを難読化・圧縮したプロダクション向けの成果物)でのみ再現するエラーは、スタックトレースが難読化されていて原因追跡が困難になります。こうした環境固有の問題を切り分けるには、ビルド種別・Reactのバージョン・ブラウザエンジンのバージョンをテストログに記録し、失敗の相関を可視化することが出発点になります。

PlaywrightやCypressといったツールは、失敗時のスクリーンショットとネットワークログを自動保存する機能を持ちます。これらを組み合わせると「どのフラグが有効で、どのAPIレスポンスが返ってきて、画面はどう見えたか」を事後に再現できます。テストが示す問題を信頼するには、テストが動作した環境の証拠を一緒に保存しておく必要があります。

ブラウザテストの信頼性は、セレクターの安定性やアサーションの精度だけでは決まりません。「どの環境を、どのデータで、どのビルドに対して実行したか」を再現可能な形で記録する仕組みが揃って初めて、緑のテスト結果が本当の意味を持ちます。

参考

When Green Browser Tests Lie: Environment Drift, CI Noise, and Hidden Runtime Failures

この記事について: 本記事は AI を活用して作成し、forva AI 編集部が内容を確認・監修しています。

AI 駆動開発のご相談は forva AI へ。まずはお気軽にどうぞ。