安定したエンド ツー エンド (E2E) テストには、外部からできるだけ隔離された環境が必要です。
フレークネスを減らす
不安定なテストは、コードに関係のない理由で失敗するテストです。アプリケーションの正当性を確認するための信頼できるチェックとして E2E を使用することは困難です。極端な場合、不安定なテストにより、チームは E2E の結果を無視するようになります。これにより、品質管理 (QA) を自動化する作業が無駄になる可能性があります。
ここで紹介するアプローチは、テスト実行における潜在的な問題の 2 つの大きな原因に対処します。
- 異なるテスト ジョブによって共有されるバックエンドによって保存された状態、および
- 制御できない外部サービス。
このアプローチの影響を受けないフレークネスの原因は他にもあります。
- 真の問題は、ランダムに表示されたアプリケーションにある、または
- アプリケーションの問題は、E2E がアプリケーションと対話する際の不自然な速度によって引き起こされます。
別
私のチームと私が専用のバックエンド コンテナーに対してテストを実行する前に、非運用サーバーの 1 つを使用しました。このアプローチは、E2E ソリューションの実験段階では問題ありませんでした。
テストが数回しかないときは、テスト結果を使用して決定を下すことはできませんでした。
しかし、テストを追加し続け、実行時間が長くなるにつれて、このアプローチは崩壊し始めました。主な問題は次のとおりです。
- テスト内のデータ変更を元に戻そうとしましたが、一部のテストの失敗により、予期しない変更が残されていました。
- 並列ジョブが衝突していました。さまざまなテスト ジョブが同じ状態を変更していたため、ジョブの 1 つが失敗することがよくありました。
すべてをDocker化する
この問題の解決策は、テスト ジョブごとに専用のバックエンド サーバーとデータベースを用意することでした。 Docker がなかったら、このアプローチは非常に困難だったでしょう。
Docker コンテナーは、アプリケーションの実行に必要なすべてのものを備えた、封じ込められた環境を作成するための完璧なツールです。
- 適切なオペレーティング システム (または、適切な Linux ディストリビューション)、
- 画像操作ライブラリなどのシステム依存関係、および
- 言語インタープリター (Python、Node など) またはデータベース サーバーの正しいバージョン。
データベース
テスト用に、予測可能なテスト データが付属する専用のデータベース コンテナーを準備できます。このようにして、各 E2E 実行の開始点を正確に再現できるため、テストがより安定します。
テスト データベースのバージョン管理のために、Docker イメージにさまざまなタグを使用できます。同じテスト データベースを開発環境でも使用できます。開発中の手動テストでは、自動テストと同様のエンティティの例が必要です。
バックエンド
バックエンドのデプロイに既に Docker を使用している場合、同じイメージを E2E の実行に再利用するのは非常に簡単です。私のチームでは、バックエンドをコンテナーとしてデプロイし、データベースの URL と資格情報を環境変数として提供しています。
まったく同じコンテナー バージョンを本番環境にデプロイしたり、テストを実行するための継続的インテグレーション (CI) で使用したりできます。各環境は、DB に接続するための適切な値を提供します。
フロントエンド
展開戦略に応じて、次のいずれかを実行できます。
構築したコンテナーをフロントエンド ビルドの一部として使用します。
コンパイルされたファイルを取得し、それらがテスト用に HTTP 経由で利用できることを確認します。
この場合、オプション 2 を使用します。アプリケーションを静的ファイルとしてデプロイするため、E2E ジョブの実行中にビルドされたファイルを提供する専用のコンテナーを作成しました。
GitLab のジョブ サービス
CI を実行するためのプラットフォームとして GitLab を使用します。 GitLab の各ジョブは、選択したイメージを含むコンテナー内で実行されます。メイン コンテナーに加えて、サービスを定義できます。テストと並行して実行される追加のコンテナーです。構成は次のように簡単です。
<job-name>: services: - name: <image> alias: <container-url>
利用可能なオプションは、Docker Compose にあるものと似ていますが、より制限されています。
GitLab 構成の 1 つの「落とし穴」は、テスト実行中にサービスが相互にアクセスできるようにする場合、変数FF_NETWORK_PER_BUILD
を 1 に設定することです。
ジョブ内分離のためのアドホック データの検討
ある時点で、1 つのジョブ内ですべてのテストを並行して実行していました。当時は、さらに強力な分離を実施する必要がありました。各テストは同じバックエンドとデータベースを使用していました。
この問題を回避するために、テストのbefore
セクションのすぐ内側に注入するランダム データに主に依存するようにテストをアップグレードしました。これにより、他のスレッドで発生する他の変更の影響を受けずにテストを実行できました。
このアプローチは、最初は少し難しいかもしれませんが、状況によっては理にかなっている場合があります。
各テスト後のクリーンアップ
テストジョブごとに新しいデータベースを開始しますが、テストがアプリケーションを見つけたときと同じ状態のままにしようとしています。たぶん、共有環境でテストを実行していた期間の残り物です。
これはもはや重要ではありませんが、次の場合にテスト開発中に役立つことがあります。
- テストを 1 つだけ実行する場合 - テストが遭遇する状態は、ファイル内のすべてのテストを実行する場合と変わりません。
- 同じテストをローカルで何度も再実行すると、データベースは以前の実行の影響を受けません。
外部サービスのモック
サービスをコンテナーに移動できない場合があります。例えば:
- アプリケーションが直接または何らかのバックエンド プロキシ経由で使用する外部サーバーがある場合、または
- 技術的な問題のためにコンテナー内で実行できないサーバーを所有しています。
どちらの場合も、テストの実行を分離するために、それらのサービスに送られるリクエストをモックできます。これにより、予測できない外部サービスがテスト結果に影響を与えるのを防ぐことができます。このアプローチの欠点は、アプリケーションが動作するコンテキストからテストが切り離されることです。
モックを配置すると、それらのサービスの変更がアプリケーションに影響を与える場合、テストはケースをキャッチしません。
学び続ける
テストやその他のプログラミング関連のトピックについて詳しく知りたい場合は、ここでサインアップして、関連コンテンツを公開したときに更新を受け取ることができます。