サイプレステストとDocker、Buildkite、CICDの統合#frontend @ twiliosendgrid

公開: 2020-12-30

Webアプリケーションがバックエンドで期待どおりに機能していることを検証するために、エンドツーエンド(E2E)のサイプレステストを多数作成しました。 これらのブラウザー自動化テストを作成した後、コードをマージして特定の環境にデプロイする前に、常にこれらのサイプレステストを実行するか、単体テストのような方法でトリガーする必要があります。 これにより、Dockerコンテナーでサイプレステストを実行して、継続的インテグレーション(CI)プロバイダーおよびクラウドでこれらのコンテナーを実行するために使用するマシンと統合するという道を歩み始めました。

デプロイフローに関しては、CIプロバイダーとしてBuildkiteを使用します。 これにより、コードを全面的に移動する場合に、Buildkiteパイプラインでアプリケーションの自動化されたステップのビルドを生成できます。 詳細については、パイプラインは通常、アプリケーションのリポジトリに関連付けられた場所であり、プルリクエストを作成し、新しいコード変更をプッシュし、コードをマスターにマージし、さまざまな環境にデプロイするときに実行する特定の手順でビルドを確認したり、ビルドをトリガーしたりできます。 展開、トリガーされたサイプレステスト、スケジュールに従って実行される特定のサイプレステストなど、個別の目的で複数のパイプラインを作成します。

このブログ投稿は、以前にサイプレステストを作成し、いくつかのテストを実行していることを前提としていますが、開発および展開フローでこれらのテストを常に実行する方法についてのアイデアが必要です。 代わりにサイプレステストの作成に関する概要を詳しく知りたい場合は、この以前のブログ投稿を確認して、実行するものがあるときにこれを再確認してください。

デプロイパイプラインでDockerComposeとBuildkiteを使用してどのように行ったかを確認することで、Dockerコンテナ内のサイプレステストをCIプロバイダーと統合する方法のアイデアを紹介することを目的としています。 これらのアイデアは、サイプレステストをトリガーするときに適用する戦略、コマンド、および環境変数について、インフラストラクチャで拡張できます。

標準のCICDフロー

標準の開発と展開のフローでは、2つのパイプラインを設定します。

  1. 1つ目は、コードをプッシュするときのデプロイメント手順を処理します。
  2. 2つ目は、サイプレステストを並行して実行し、記録するようにトリガーします。 これの成功または失敗は、デプロイメントパイプラインに影響します。

デプロイパイプラインでは、Webアプリケーションアセットを構築し、単体テストを実行し、各環境にデプロイする前に、選択したサイプレステストをトリガーする手順を実行します。 プッシュボタン展開を実行する機能を無効にする前に、それらが合格することを確認します。 2番目のパイプラインでトリガーされたこれらのサイプレステストもDockerコンテナーで実行され、記録キーを介して有料のサイプレスダッシュボードに接続されるため、これらのサイプレステストからのビデオ、スクリーンショット、コンソール出力を振り返って問題をデバッグできます。

Buildkiteの選択入力を使用して、動的な独自の冒険を考案し、ユーザーが「はい」または「いいえ」を選択して、実行するサイプレス仕様フォルダーを決定し、コードをプッシュするときに検証できるようにしました。 デフォルトの回答はすべてのオプションで「いいえ」ですが、「はい」の値はサイプレス仕様フォルダーへのグロブパスになります。

コードの変更が他のページに影響を与えない場合は、すべてのサイプレステストを実行したくない場合があります。 代わりに、影響を受けることがわかっているテストのみをトリガーします。 また、トリガーするテストの数に応じて0〜10分かかる可能性のあるサイプレステストを実行しないのに十分な自信があるため、緊急のバグの問題に対して本番環境にクイックフィックスをデプロイする必要がある場合があります。 この部分の視覚的およびYMLステップの両方で例を提供します。

次に、 runCypress.shという独自のBashスクリプトを実装して、選択した「はい」または「いいえ」の値を解析するための選択ステップの後に実行します。 これを実行して、実行するコンマ区切りのスペックパスのリストを作成し、トリガーされたパイプラインのDockerコンテナで実行される最終的なサイプレスコマンドにオプション--specとして追加します。 「CYPRESS_SPECS」の仕様の形成リストや「CYPRESS_TEST_ENV」の現在のテスト環境などの環境変数をエクスポートして、スクリプトの最後にbuildkite-agent pipeline upload "$DIRNAME"/triggerCypress.ymlでトリガーするパイプラインで使用しますbuildkite-agent pipeline upload "$DIRNAME"/triggerCypress.yml

「ASYNC」環境変数もエクスポートする方法にお気づきかもしれません。 Buildkiteでは、トリガーされたビルドステップを、成功または失敗の観点からブロックするか非ブロックにするかを選択できます。 「ASYNC」がtrueに設定されている場合、メインのデプロイメントパイプラインステップは引き続き実行され、別のパイプラインでトリガーされたサイプレステストが終了するのを待ちません。 パイプラインの成功または失敗は、デプロイメントパイプラインの成功または失敗に影響を与えません。

「ASYNC」をfalseに設定すると、別のパイプラインでトリガーされたサイプレステストが終了するまで、メインのデプロイパイプラインステップがブロックされます。 トリガーされたビルドの成功または失敗は、デプロイメントパイプラインの全体的な成功または失敗につながります。

プルリクエストが開いた状態でコードがまだ機能ブランチにある場合は、さらに変更をプッシュし、サイプレステストをトリガーして、動作を確認します。 ただし、途中でさらに多くの変更が行われる可能性があるため、トリガーされたテストが失敗した場合に、残りのデプロイメントパイプラインステップの実行を常にブロックする必要はありません。 このシナリオでは、「ASYNC」をfalseに設定して、サイプレスのテストが失敗した場合にブロックしないようにします。 プルリクエストをすでにマスターにマージしてステージングにデプロイしたが、本番環境にデプロイする前にサイプレステストをトリガーしたい場合は、本番環境に移行する前にサイプレステストを常に合格させたいので、「ASYNC」をtrueに設定します。 。

runCypress.shに戻ると、スクリプトが、割り当てられた環境変数値を使用してtriggerCypress.ymlファイルを呼び出すことにより、実行する2番目のパイプラインをトリガーすることを思い出します。 triggerCypress.ymlファイルは次のようになります。 「トリガー」ステップとビルドメッセージへの値の補間は、デバッグと動的ステップ名に役立ちます。

サイプレステストをトリガーしてデプロイメントパイプラインから別のトリガーパイプラインに実行する場合でも、専用パイプラインでスケジュールに従ってサイプレステストを実行する場合でも、環境変数の値を変更するだけで、同じ手順を実行して再利用します。

これらの手順には次のものが含まれます。

  1. 最新のタグと一意のバージョンタグを使用してDockerイメージを構築する
  2. Dockerイメージをプライベートレジストリにプッシュする
  3. 同じイメージをプルダウンして、Dockerコンテナの環境変数値に基づいてサイプレステストを実行します

これらの手順は、次のようにpipeline.cypress.ymlファイルで概説されています。

サイプレステストを実行するようにトリガーすると、サイプレストリガーパイプラインで別のビルドが開始されます。 ビルドの成功または失敗に基づいて、サイプレスのテスト実行は、マスターブランチビルドのステージングから本番環境に移行するときに、本番環境へのデプロイをブロックまたは許可します。

「トリガーされたヒノキ/統合/…」ステップをクリックすると、このようなビューでトリガーされたパイプラインのビルドに移動し、テストがどのように行われたかを確認できます。

Dockerパーツがすべてどのように接続されているかについて知りたい場合は、 Dockerfile.cypressとdocker docker-compose.cypress.ymlがパイプラインからエクスポートされた環境変数を使用して、右向きのアプリケーションのpackage.jsonから適切なCypressコマンドを使用します。環境をテストし、選択したスペックファイルを実行します。 以下のスニペットは、拡張してより柔軟にするために改善できる一般的なアプローチを示しています。


通常の統合および展開サイクル中に実行されるテスト以外に、専用のBuildkiteパイプラインを作成しました。 これらのパイプラインは、ステージング環境に対する重要なテストのスケジュールに従って実行され、フロントエンドサービスとバックエンドサービスが正しく機能していることを確認します。 同様のパイプライン手順を再利用し、Buildkiteパイプラインの設定で特定の環境変数値を調整し、スケジュールされた時間に実行されるようにcronスケジュールを設定しました。 これにより、テストの実行状況を引き続き監視し、ダウンストリームまたは独自のコードプッシュによってテストが失敗する可能性があるかどうかを監視しながら、ステージング環境に関する多くのバグや問題を見つけることができます。

並列化

また、並列化フラグを利用して、OpsチームによってセットアップされたビルドエージェントのキューからスピンアップできるAWSマシンの数を活用します。 この並列化フラグを使用すると、Cypressは、Buildkiteの「並列処理」プロパティで設定した数に基づいて、特定の数のマシンを自動的に起動します。

アプリケーションリポジトリの1つで、約5分で200を超えるテストを実行できました。

次に、特定のビルド実行の各テストの記録を維持しながら、すべてのサイプレステストをそれらのマシン間で並行して実行するように分散します。 これにより、テストの実行時間が劇的に増加しました。

サイプレステストを並列化する際のヒントは次のとおりです。

  • 最適なマシン数についてはダッシュボードサービスの提案に従い、パイプラインの柔軟性を高めるために環境変数にマシン数を設定してください。
  • 小さなテストファイルに分割します。特に、実行時間の長いテストをチャンクに分割すると、マシン間でより適切に並列化できます。
  • サイプレステストが分離されており、相互に影響を与えたり、相互に依存したりしないようにしてください。 更新、作成、または削除に関連するフローを処理するときは、別々のユーザーとデータリソースを使用して、テストが互いに踏みにじられ、競合状態に陥らないようにします。 テストファイルは任意の順序で実行できるため、すべてのテストを実行するときに問題にならないようにしてください。
  • Buildkiteの場合、 parallelオプションに加えて、BuildkiteビルドID環境変数値を--ci-build-idオプションに渡すことを忘れないでください。これにより、マシン間でテストを並列化するときに、どの一意のビルド実行を関連付けるかがわかります。

レビューする:

サイプレステストをBuildkiteなどのCIプロバイダーに接続するには、次のことを行う必要があります。

  1. 特定のブラウザーに対してノード環境でテストを実行するために必要なサイプレスベースイメージと依存関係を使用して、アプリケーションコードでDockerイメージを構築します。
  2. Dockerイメージを特定のタグを使用してレジストリにプッシュします
  3. 後の手順で同じ画像をプルダウンします
  4. サイプレスダッシュボードサービスを使用している場合は、ヘッドレスモードで、記録キーを使用してサイプレステストを実行します。
  5. さまざまな環境変数値を設定し、それらをCypressに対して実行するコマンドにプラグインして、それらのDockerコンテナー内の特定のテスト環境に対して選択されたCypressテストをトリガーします。

これらの一般的な手順は、再利用して、スケジュールで実行されるサイプレステストや、展開パイプラインに加えて選択したブラウザーに対して実行するテストのトリガーなどの他のユースケースに適用できます。 重要なのは、CIプロバイダーの機能を活用し、環境変数の値に基づいて柔軟で構成可能なコマンドを設定することです。

環境変数の値に基づいて柔軟で構成可能なようにコマンドを設定します。

CIプロバイダーを使用してDockerでテストを実行すると(ダッシュボードサービスの料金を支払う場合)、複数のマシン間でテストを並列化することを利用できます。 テストが互いに踏みにじられるのを避けるために、既存のテストとリソースを変更して、それらが別のものに依存しないようにする必要がある場合があります。

また、バックエンドAPIを検証するためのテストスイートを作成したり、選択したブラウザーに対して実行するテストをトリガーしたりするなど、自分で試すことができるアイデアについても説明しました。 サイプレスのドキュメントには、継続的インテグレーションを設定する方法が他にもあります

さらに、展開フローまたはスケジュールされた間隔でこれらのサイプレステストを実行して、開発環境が常に期待どおりに機能していることを確認することが重要です。 サイプレスのテストで、ダウンした、または何らかの方法で変更されたダウンストリームバックエンドサービスに関連する問題が検出され、フロントエンドアプリケーションエラーが発生することが何度もありました。 特に、新しいReactコードの変更をプッシュした後、Webページの予期しないバグから私たちを救いました。

合格したテストを維持し、テスト環境で失敗したテストの実行を注意深く監視することで、サポートチケットが減り、本番環境での顧客の満足度が高まります。 新しいコード変更をプッシュするときに、健全で安定した一連のサイプレステストを実行し続けることで、問題がうまく機能しているという確信が高まります。サイプレステストでも同じことを行うことをお勧めします。

サイプレステストのその他のリソースについては、次の記事を確認してください。

  • E2Eテストを書くときに考慮すべきこと
  • サイプレステストの作成の1,000フィートの概要
  • TypeScriptサイプレステストのすべてのもの
  • サイプレステストでの電子メールフローの処理
  • サイプレステストを構成、整理、統合するためのアイデア