エンド・ツー・エンド・テスト

エンドツーエンドテストとは何ですか?

エンドツーエンド(e2e)テストは、アプリケーションがソフトウェアスタックとアーキテクチャ全体にわたって期待通りに動作するかどうかをチェックするために使用される戦略です。

GitLabをどのようにテストするのですか?

Omnibus GitLabを使ってGitLabパッケージをビルドし、GitLab QAオーケストレータツールを使ってこれらのパッケージをテストし、qa ディレクトリにあるエンドツーエンドのテストを実行します。

さらに、GitLab Development Kit (GDK) をテスト環境として使用し、迅速にデプロイすることで、より迅速なテストフィードバックを実現しています。

ナイトリービルドのテスト

Omnibus が作成したナイトリービルドをテストするために、毎晩スケジュールされたパイプラインを実行しています。これらのパイプラインはhttps://gitlab.com/gitlab-org/gitlab/-/pipeline_schedules にあります (開発者ロールが必要です)。結果は#qa-master Slack チャンネルでレポーターされます。

ステージングのテスト

ステージングをテストするために、毎晩スケジュールされたパイプラインを実行しています。これらのパイプラインはhttps://gitlab.com/gitlab-org/quality/staging/pipelines にあります (開発者ロールが必要です)。結果は#qa-staging Slack チャンネルでレポーターされます。

マージリクエストのコードのテスト

パッケージとテストのジョブの使用

qa ステージでe2e:package-and-test の手動アクションをトリガーすることで、マージリクエストに対してエンドツーエンドのテストを実行することができます (フォークでは利用できません)。

これはマージリクエストの変更からビルドされたカスタムEE(Ultimateライセンス)Dockerイメージに対してエンドツーエンドのテストを実行します。

エンドツーエンドテストを開始する手動アクションはgitlab-org/omnibus-gitlab マージリクエスト でも利用できます。

どのように動作しますか?

現在、Omnibus GitLabに対してエンドツーエンドのパイプラインを実行するために、_マルチプロジェクトパイプラインのような_アプローチを使っています。

graph TB A1 -.->|once done, can be triggered| A2 A2 -.->|1. Triggers an `omnibus-gitlab-mirror` pipeline<br>and wait for it to be done| B1 B2[`Trigger-qa` stage<br>`Trigger:qa-test` job] -.->|2. Triggers a `gitlab-qa-mirror` pipeline<br>and wait for it to be done| C1 subgraph "`gitlab-org/gitlab` pipeline" A1[`build-images` stage<br>`build-qa-image` and `build-assets-image` jobs] A2[`qa` stage<br>`e2e:package-and-test` job] end subgraph "`gitlab-org/build/omnibus-gitlab-mirror` pipeline" B1[`Trigger-docker` stage<br>`Trigger:gitlab-docker` job] -->|once done| B2 end subgraph "`gitlab-org/gitlab-qa-mirror` pipeline" C1>End-to-end jobs run] end
  1. gitlab-org/gitlab パイプライン
    1. 開発者は、GitLab のマージリクエストにあるe2e:package-and-test 手動アクション (build-qa-imagebuild-assets-image のジョブが完了すると利用可能になります) をトリガーします。これは e2e テスト子パイプラインを開始します。
    2. E2E 子パイプラインはgitlab-org/build/omnibus-gitlab-mirror のダウンストリームパイプラインをトリガーし、結果のステータスをポーリングします。これを_ステータスの帰属と_呼びます。
  2. gitlab-org/build/omnibus-gitlab-mirror パイプライン
    1. Dockerイメージがビルドされ、コンテナレジストリにプッシュされます。
    2. Dockerイメージがビルドされ、プッシュされると、test ステージのジョブが開始されます。
  3. Test ステージで
    1. gitlab-org/build/omnibus-gitlab-mirror レジストリに保存されたDockerイメージのコンテナがスピンアップされます。
    2. エンドツーエンドのテストは、gitlab-qa 実行ファイルを使用して実行され、gitlab-org/gitlab レジストリからエンドツーエンドイメージのコンテナがスピンアップされます。
note
の代わりにgitlab-org/build/omnibus-gitlab-mirror を使っていることにお気づきかもしれません。 これは、gitlab-org/omnibus-gitlabGitLab の権限モデルに技術的な制限があるためです。保護されたブランチに対してパイプラインを実行する能力は、そのブランチにプッシュ/マージする能力によって制御さ gitlab-org/omnibus-gitlabれます。gitlab-org/omnibus-gitlabつまり、開発者がデフォルトブランチに対してパイプラインを実行 gitlab-org/omnibus-gitlabするには、このプロジェクトのメンテナーのロールが必要だということです。セキュリティ上の理由や意味合いから、デフォルトブランチをすべての開発者に公開することはできませんでした。そこで私たちはこのミラーを作成し、開発者やメンテナーがデフォルトブランチにプッシュ/マージできるようにしました。この問題はhttps://gitlab.com/gitlab-org/gitlab-qa/-/issues/63#note_107175160 で発見され、「ミラー」による回避策はhttps://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/4717で提案されました。パイプラインの実行とプッシュ/マージに関するアクセス制御を分離する機能提案も、https://gitlab.com/gitlab-org/gitlab/-/issues/24585で作成されました。

CI/CD のセットアップに関する技術的な詳細や、e2e:package-and-test パイプラインに新しいテストジョブを追加するドキュメントについては、e2e:package_and_test セットアップドキュメント を参照してください。

test-on-gdk ジョブの使い方

e2e:test-on-gdk ジョブはほとんどのマージリクエストで自動的に実行され、マージリクエストの変更から GDK インスタンスをビルドしてインストールし、その GDK インスタンスに対してエンドツーエンドのテストを実行する子パイプラインをトリガーします。

どのように動作しますか?

gitlab-org/gitlab パイプライン

  1. build-gdk-image ジョブ はマージリクエストのコードを使用して、GDKインスタンス用のDockerイメージを構築します。
  2. e2e:test-on-gdk トリガージョブは、前のジョブで構築されたイメージから起動されたGDKインスタンスに対してエンドツーエンドのテストを実行する子パイプラインを作成します。

詳細については、e2e:test-on-gdk パイプライン](test_pipelines.md#e2etest-on-gdk) の[ドキュメントを参照してください。

マージ結果のパイプラインでは

マージ結果パイプラインでは、パイプラインはソースブランチとターゲットブランチのマージ結果を含む新しい ref で実行されます。

マージ結果パイプラインのエンドツーエンドテストでは、マージリクエストソースブランチの先頭ではなく、新しい ref を使用します。

graph LR A["x1y1z1 - master HEAD"] B["d1e1f1 - merged results (CI_COMMIT_SHA)"] A --> B B --> C["Merged results pipeline"] C --> D["E2E tests"]
カスタムテストの実行

ダウンストリームgitlab-qa-mirror パイプラインで実行される既存のシナリオには多くのテストが含まれていますが、既存のシナリオのグループとは異なるテストやテストグループを実行したい場合があります。

例えば、欠陥のあるテストの検疫を解除する場合、まず欠陥がなくなったことを確認します。そのためには、_ee:quarantine 手動ジョブを実行します。手動ジョブの名前(再生アイコンではありません)を選択すると、変数の入力を求められます。gitlab-qa](https://gitlab.com/gitlab-org/gitlab-qa/blob/master/docs/what_tests_can_be_run.md#supported-gitlab-environment-variables) で使える変数だけでなく、[の変数も使えます:

変数|説明|-|-||QA_SCENARIO |実行するシナリオ(デフォルトTest::Instance::Image )|QA_TESTS |実行するテスト(デフォルトなし、つまりシナリオ内の全てのテストを実行)。ファイルパスは、RSpec でテストを実行するときと同じように使用します。例えば、qa/specs/features/ee/browser_ui の場合、EE の UI テストが全て含まれます。QA_RSPEC_TAGS追加する RSpec タグ(デフォルトは--tag quarantine)。

今のところ、カスタム変数を指定した手動ジョブは、再試行時に同じ変数を使用しません。したがって、同じテストを複数回実行したい場合は、custom-parallel の各ジョブで同じ変数を指定してください (実行可能な 10 ジョブのうち、実行したいジョブの数まで)。

review-qa-all ジョブの使用法

test ステージ中のすべてのパイプラインで、review-qa-smoke ジョブが自動的に開始されます: このジョブはレビューアプリに対して QA スモークスイートを実行します。

手動でreview-qa-all を起動することもできます:レビューアプリに対して完全なQAスイートを実行します。

これは、公式の GitLab Helm チャートに基づいたレビューアプリに対してエンドツーエンドのテストを実行し、それ自体はマージリクエストの変更からビルドされたカスタムCloud Native コンポーネントでデプロイされます。

レビューアプリの詳細についてはレビューアプリをご覧ください。

選択的テスト実行

マージリクエストで実行されるテストの量を制限するために、実行するテストの動的選択があります。実行するテストのアルゴリズムは、変更されたファイルとマージリクエストラベルに基づいています。どのテストが実行されるかは、以下の基準によって決定されます:

  1. qa フレームワークのコードが変更された場合、全テストが実行されます。
  2. qa フォルダ内の特定の_spec.rb ファイルを変更すると、その特定のテストだけが実行されます。この場合、knapsack はジョブの並列実行には使われません。
  3. バックエンドの変更とラベルdevops::manage を含むマージリクエストでは、manage ステージに関連するすべての e2e テストが実行されます。この場合、ジョブは knapsack を使って並列に実行されます。

選択的なテスト実行の上書き

選択的テスト実行を無効にして完全なスイートを起動するには、pipeline:run-all-e2e のラベルを特定のマージリクエストに追加します。

テストの並列実行

CI上でテストを並列実行するには、Knapsackgemを使います。Knapsack のレポーターは自動的に生成され、gitlab-qa-resources プロジェクトのGCS バケットknapsack-reports に保存されます。KnapsackReport ヘルパーがレポートの自動生成とアップロードを行います。

テストのメトリクス

テストの健全性をさらに可視化するには、カスタムセットアップを使用してテストの実行結果をInfluxDbインスタンスにエクスポートし、結果をGrafanaダッシュボードとして可視化します。

プロビジョニング

すべてのコンポーネントのプロビジョニングは、engineering-productivity-infrastructure プロジェクトによって実行されます。

CIでのメトリクスのエクスポート

これらの環境変数を使用して、メトリクスのエクスポートを設定します:

変数必須インフォメーション
QA_INFLUXDB_URLtrue https://influxdb.quality.gitlab.net に設定する必要があります。 デフォルト値はありません。
QA_INFLUXDB_TOKENtrue Gitlab-QA 1Password データ保管庫のInfluxdb auth tokens ドキュメントの下にある InfluxDB 書き込みトークン。デフォルト値なし。
QA_RUN_TYPEfalse e2e:package-and-test のように、テスト実行のための任意の名前。ライブ環境でのテスト実行時に、プロジェクト名から自動的に推測されます。デフォルト値なし。
QA_EXPORT_TEST_METRICSfalseInfluxDB へのメトリクスのエクスポートを有効または無効にするフラグ。デフォルトはfalse です。
QA_SAVE_TEST_METRICSfalseメトリクスを JSON ファイルとして保存することを有効または無効にするフラグ。デフォルトはfalse です。

テスト・レポーター

アリュールレポート

パイプライン上で実行されるテストは、Allureテストレポートを生成し、ホストします。

QA フレームワークはAllure RSpecgem を使ってAllure テストレポートのソースファイルを生成しています。パイプラインの追加ジョブ:

  • すべてのテストジョブからこれらのソースファイルを取得します。
  • レポートを作成し、AWS グループプロジェクトeng-quality-ops-ci-cd-shared-infraにあるS3 バケットgitlab-qa-allure-report にアップロードします。

レポートアップロード用の共通 CI テンプレートはallure-report.ymlに格納されています。

マージリクエスト

これらのテストがマージリクエストの範囲で実行されると、Allure レポートがGCS バケットにアップロードされ、それぞれのレポートにリンクするコメントが追加されます。

スケジュールされたパイプライン

これらのテスト用のスケジュールされたパイプラインには、Report ステージの下にgenerate-allure-report ジョブが含まれます。また、現在のテストレポートへのリンクも出力されます。

スケジュールされたパイプラインの各タイプは、そのステージに応じて、最新のテストレポー トの静的リンクを生成します:

テストの実行方法は?

マージリクエストでコードをテストしていない場合、テストを実行するには主に2つの選択肢があります。既存のテストをGitLabのライブインスタンスやビルド済みのDockerイメージに対して実行したい場合は、GitLab QAオーケストレーターを使います。オーケストレータを使って実行できるテストシナリオの例もご覧ください。

一方、ローカルの開発GitLab環境に対して実行したい場合は、GitLab Development Kit(GDK) を使用できます。QA READMEと以下のセクションの説明を参照してください。

特別な設定が必要なテストの実行

ローカル環境で実行するために特別な設定や配慮が必要なテストの実行方法について説明します。

テストの書き方は?

新しいテストを書く前に、GitLab QAアーキテクチャをレビューしましょう。

テスト環境オーケストレーションシナリオと インスタンスレベルシナリオをどこに置くかを決めたら、GitLab QA READMEGitLab QA オーケストレータ README、そして既に存在するインスタンスレベルシナリオを見てみましょう。

エンドツーエンドのテストを書かないことを検討

エンドツーエンドのテストについては、以下のベストプラクティスに従うべきです:

  • 下位レベルの機能テストが存在する場合は、エンドツーエンドのテストを書かないようにしましょう。エンドツーエンドのテストは、より多くの作業とリソースを必要とします。
  • エンドツーエンドテストのトラブルシューティングは、テスト対象のアプリケーションへの接続が不明なため、 より複雑になる可能性があります。

引き続きお読みください:

どこに助けを求めますか?

Slack の#quality チャンネル (GitLab 内部) で質問したり、 gitlab issue trackergitlab-qa issue trackerで作業したいイシューを見つけることができます。