ラクスルの@nnm_techです。
ラクスルの印刷サービスではこれまでにもE2Eテストがありましたが、この度より良いシステムを目指し再構築することになりました。 本記事ではTestCafeとAWS CodeBuildを用いたE2Eテスト刷新について紹介したいと思います。
ラクスルで運用している印刷サービスは裏側で複数のサービスが協調動作しています。 入稿サービス、発注サービス、決済サービス…外部サービスとの連携も含めるとかなりの数があります。
このような中、弊社では各サービスの変更時におけるユースケースの動作担保・リグレッション検知を目的にE2Eテストを実施しています。
目次
E2Eテストを構築するにあたってのポイント
ポイント1: テストの書きやすさ
E2Eテストはどうしても機能開発に比べると優先順位が下がるため、往々にして放置されやすいです。 そのためメンテナンスコストができる限り低い状態が好ましいです。
ポイント2: 実行環境のセットアップ
E2Eテストは実行時にブラウザやWebDriverなど実行に必要な物が多くなりがちです。 CIツールへの導入時や、エンジニアの手元での開発を考慮すると簡単にセットアップできるものが好ましいです。
ポイント3: 実行タイミング
E2Eテストはプロダクションへのリリース前に実行され、直近の変更に問題がないか担保されているのが好ましいです。 masterブランチへのマージ後に実行すると、いつプロダクションにデプロイされてもおかしくなくそれでは遅いと考えています。
開発ブランチプッシュのたびに実行するのも一つの手ですが、E2Eテストはある程度時間がかかるためリソースを長く専有してしまいます。 いい塩梅で実行されると嬉しいです。
これまで
さてラクスルの印刷サービスではどうなのかというと、これまでのラクスルのE2Eテストでは以下の2つが主に実行されていました。
- Mocha + Chaiを用いた簡単な疎通確認テスト
- Nightwatch.jsを用いたE2Eテスト
上記も悪くないですが、より多くのエンジニアにとって書きやすい選択肢を模索しました。 特に弊社、現状サーバーサイドエンジニアの比率が多く、サーバーサイドエンジニアがE2Eテストを書くことも多いです。
誰にとっても書きやすいテストフレームワークが求められます。
また既存のE2Eテストの実行環境はJenkinsを使用しておりましたが、Jenkinsサーバに対してE2Eテストを実行するために必要なツール(ヘッドレスブラウザ等)をインストールしておく必要がありました。Jenkinsサーバのセットアップの煩雑さや、パッケージの依存関係などで他の関係無いジョブへ影響あたえる可能性があるなどの課題がありました。
というわけでテストフレームワークとその実行環境を中心的に改善してみました。
どうしたか
テストの書きやすさ: TestCafeの導入
E2Eテストのテストフレームワークとして新しくTestCafeを採用しました。
https://github.com/DevExpress/testcafe
TestCafeの特徴を簡単に表すと、
- セットアップが容易。WebDriverをインストールする必要が無い
npm install -g testcafe
で終了!- 公式では1分でセットアップが完了すると謳っている
- async/awaitを前提としたAPI設計がされている
- 明示的に待機するコードを書く必要が無い
- テストはJavaScript/TypeScriptで記述する
- Seleniumはいろいろな言語で記述できた
- 並列実行可能
- 主要なOSをサポートしている。Windows, MacOS, Linux
- BrowserStackとの連携で金の弾丸でテスト環境を増やすこともできる
セットアップのしやすさからテストの書きやすさ、様々な環境、ブラウザでのテストがしやすいのでとても良いです。
実行環境: AWS CodeBuildの導入
TestCafeのテスト実行はAWS CodeBuild上で行うようにしました。
https://aws.amazon.com/jp/codebuild/
AWS CodeBuildの特徴を簡単に表すと、
- CircleCIと似ている
- BuildSpecを用いたタスクの定義
- GitHubレポジトリとの容易な連携
- Linux or Windowsを選択可能
- Dockerを用いたタスクの実行
- 公式が提供している
Ruby
やNode.js
などの実行環境を指定することができる。各環境のDockerFileは公開されている - 自前のDocker Imageを用いてタスク実行することができる
- 公式が提供している
- AWSのサービスなので何かと設定が楽
- ECRとの連携が簡単
- 成果物(Artifacts)もS3に簡単に配置できる
- ローカルでの動作確認もできる
- Jenkins連携がとても楽
- EC2でJenkinsを動かしている場合は連携時のCredentialが不要(参考)
- ビルドするSource、環境変数、Artifactの保存先、ログ設定、Parameter Store(Build Spec内で利用する変数)はJenkinsのジョブ設定で変更することが可能
- AWS CodeBuildのCloudWatch LogsがJenkinsからいい感じで閲覧できる
ラクスルの印刷チームではnodeとchromiumがインストールされたAlpine LinuxのDockerイメージをECRに配置し、 AWS CodeBuildのTestCafe実行環境として利用しています。
AWS CodeBuildの実行はJenkinsを利用しています。 既存E2Eテストの資産もあるため、実行はJenkinsをベースに、TestCafeのテストをBuildPipelineの1ステージとして組み込むことで
新旧のテストを実行しています。AWS CodeBuildはビルドのキューイングができず複数のビルドが同時に処理されてしまうため、 キュー管理の観点からもJenkins連携する利点もあります。
実行タイミング: QA環境での受入時の実行
ラクスルでは修正のリリース前にエンジニアやプロダクトマネージャによるQA環境での受入確認プロセスがあります。
QA環境は本番とほぼ同等のテスト環境であり、このQA環境での受け入れ確認用の各サービスのブランチプッシュをトリガーとしてE2Eテストが走るようにしました。 これにより本番リリースする前に程よい頻度でのテスト実行ができます。
結果
TestCafeがとても書きやすく、ドキュメントも充実しているためサーバーサイドエンジニアが苦なくテストを書けています。 エンジニアの種別に関係なくテストが書きやすい環境ができました。
テストの実行自体もAWS CodeBuildのローカル実行ができるのでセットアップも楽に。 ただしTestCafeのセットアップが本当に楽なのでみんなローカルでnpm installしてるようです。
AWS CodeBuild、特になんの問題もなく動いてくれていて非常に良いです。今後今回のようなケース以外でもAWS CodeBuildを多用することで Jenkinsの管理コストが下がりそうです。
運用中に発見した課題として、Fail時の素早い復旧があります。新システムの運用後、Failする機会があったのですが、その時点での各サービスの情報を取得するのに時間がかなりかかりました。Fail時に各サービスのgitのrefやauthor情報をSlackに通知することで対応しやすくしました。
まとめ
ラクスル印刷サービスでのE2Eテスト改善についてTestCafeとAWS CodeBuildの概要を交えつつご紹介させていただきました。 今回の刷新にあたってフロントエンドエンジニアやサーバーサイドエンジニアの皆と検討しながら行いました。
ラクスルのエンジニアは改善策を提案したり、実行できる人が多く(その節はありがとうございました)、 他チームと話していく中でもすでに改善策が色々と出ているので、これからもどんどん良くしていければと思います。