はじめに
はじめまして。Web アプリケーションの QA エンジニアとして、E2E の自動テストの作成と運用保守をしています。
今日は、その中で考えてきた自動テストの保守性について、私なりの考えを書いてみようと思います。ツールは MagicPod を使っていて、本記事はその運用を前提に書いています。
私の現場では、毎日コードをデプロイしているため、回帰確認も毎日行っています。回帰確認の観点を E2E の自動テストにして、夜間に流し、朝に結果を確認しています。「前回から変わっていないこと」を確認するテストなので、画面や仕様が変わればテストは落ち、それに合わせてテストを直します。この直しやすさが、本記事でいう保守性です。直すには、まず何が原因で落ちたかを突き止め、次に直す場所を絞る必要があります。そのため大事にしているのは 2 つです。
- テスト結果が Fail になったときに、原因に辿り着けること
- 同じ修正を、テストケースを跨いで繰り返さないこと
この 2 つを満たすために、テストケースの組み方で決めている 3 つのことを、次の順で 1 つずつ記事にしていきます。
- テストケースの骨格(準備 → テスト → 後処理を 1 ケースに収める)
- ステップの共通化(操作を共有ステップという共通部品にして、ケースはそれを呼ぶだけにする)
- 変数の使い方(テナント・ユーザー・ランダム値を変数で持つ)
本記事は 1 つ目、骨格についてです。1 ケースの中の組み方に絞って書きます。複数のケースをまとめて流す運用(並列実行など)は、別の記事で書きます。
1. ケースの骨格
骨格として決めているのは、各ケースが自分の準備と後処理を持ち、ほかのケースに頼らないことです。MagicPod のケースでは、それを準備・テスト・後処理の三段として 1 ケースに収めます。例は、あるショッピングサイトの商品管理画面で、商品カテゴリが親、商品が子の親子データを扱うものだと思ってください。
[準備] テストに必要なデータを、このケース専用に作る
(商品カテゴリを作成 → 商品を登録)
↓
[テスト] 確認したい業務の流れを通し、期待値を検証する
(例: 商品一覧でカテゴリを絞り込み、登録した商品が表示されること)
↓
[後処理] 準備で作ったデータを、作った順の逆に消す
(商品を削除 → 商品カテゴリを削除)
三段が目で追えるように、操作をしない「コメント」コマンドで「準備」「テスト」「後処理」と書いた区切りを入れています。MagicPod のケースは、ステップを上から順に並べた一本の列なので、この区切りがあると工程の境目が見えます。
準備で作るのは、テストが見たり変えたりするデータです。親のカテゴリも含めて、そのケースで作ります。環境に置いておくのは、ログインに使うテナントとユーザーだけです。
図の準備で作る商品カテゴリと商品は、利用者と同じ画面の操作で作っています。データを直接入れる方が速いですが、画面を通して作ると、業務の処理を経た整合の取れたデータになります。準備で通る画面の不具合も、そこで拾えます。
三段のうち主役はテストで、準備と後処理はテストを成り立たせるための脇役です。この脇役を同じケースに含めることで、落ちたときに調べやすくなります。
2.なぜこの構造か
「はじめに」で挙げた 2 点のうち、骨格が効くのは「Fail の原因に辿り着けること」です。もう 1 つは、次の記事のステップの共通化で書きます。骨格の効き方は 2 つあります。そのあとに、MagicPod ならではの注意点を書きます。
落ちた工程が分かる
準備・テスト・後処理の三段に分かれていて、区切りのコメントも入れてあるので、落ちたステップから直前の区切りを遡れば、どの工程で落ちたかすぐ見分けられます。準備で落ちたなら前提データの作成、テストで落ちたなら確認対象そのもの、後処理で落ちたなら片づけ、と調査の入口が違います。後処理で落ちたケースは、テスト工程までは通っています。Flaky なら単独で流し直して通ることを確かめ、アプリの不具合なら Fail として報告します。
準備の操作は多くのケースで同じ画面を同じ手順で使うので、複数のケースが同じ準備で揃って落ちていれば、ケースごとに偶然落ちたのではなく、その準備で使う画面に共通の原因があると絞れます。
単独で流し直せる
準備で自分の前提を作り、後処理で自分の片づけをするケースは、ほかのケースの実行結果に頼りません。ケースが作るデータは名前の末尾に実行時刻を入れていて、残ったデータとぶつからず、見分けもつきます。そのため、落ちたケースだけを、ほかのケースを先に流さずにそのまま流し直し、結果もそのまま調べられます。
準備や後処理を、先に流す別のケースに切り出したり、ほかのケースが作ったデータに頼ったりすると、ケースの間に実行順の依存が生まれます。後処理を手作業にすれば、流し直すたびに人の手が要ります。データを作って確認するテストを毎日流す前提だと、どれも運用が続きません。落ちた工程が分かり、単独で流し直せる。この 2 つのために、準備・テスト・後処理の三段を 1 ケースに収めています。
MagicPod では途中で落ちるとデータが残る
準備やテストの途中でステップが落ちると、そこでケースの実行が止まり、後処理まで進まずに、それまでに作ったデータが残ります。残ったデータが溜まらないよう、次にテストを流す前にクリーンアップ用のケースでまとめて削除します。
後処理は各ケースに残し、クリーンアップはその取りこぼしを拾う保険にしています。通ったケースが何も残さなければ、残っているデータは落ちたケースのものだけになり、そのまま調べられるからです。
おわりに
E2E のテストケースを、準備・テスト・後処理の三段で 1 ケースに収める話を書きました。この構造にしておくと、落ちた工程が分かり、落ちたケースだけを流し直せます。これが、Fail の原因に辿り着くための土台だと考えています。
次回は、組み方で決めている 3 つのうち 2 つ目、ステップの共通化について書きます。操作を共有ステップに切り出して、ケース側には業務の流れだけを残す組み方と、それで同じ修正をテストケースを跨いで繰り返さずに済む理由を扱います。
最後まで読んでいただき、ありがとうございました。