前回の記事で「足りなかったのは、既存を守るテストを蓄積して毎回走らせる仕組み」と書いた。その仕組みを具体的にどう作るか、相談しながら決めたことを、後で読み返す用にまとめておく。
先に、世界基準の知見を確認した
自分たちで発明する必要はなく、確立された考え方の組み合わせで足りる。役割で分けると 4 つに整理できる。
| 役割 | 知見 | 出どころ |
|---|---|---|
| 何を試すか | テストピラミッド、リスクベーステスト、クリティカルユーザージャーニー | Mike Cohn、ISTQB、Google SRE |
| いつ・どこで試すか | デプロイメントパイプライン、トランクベース開発、プレビュー環境、密閉テスト | 『Continuous Delivery』、Google Testing Blog、Vercel などの慣行 |
| 壊れにくく保つ | flaky(不安定な)テストの扱い、DORA の 4 指標 | Google の flaky 研究、『Accelerate』 |
| どう書くか | Playwright の公式ベストプラクティス、契約テスト | Playwright docs、Pact |
自分たちの状況で特に効くのは「密閉テスト(CI をステージングから切り離す)」と「flaky の扱い(放置すると赤でもマージが常態化する)」の 2 つ。ただし Playwright を使わないという意味ではない。Playwright は「どう書くか」の道具で、回帰テストの E2E はすべてこれで書く。
用語の確認: クリティカルユーザージャーニー
「クリティカル」という言葉は 3 つの意味で使われていた。
- クリティカルユーザージャーニー(CUJ): これができなければサービスとして成立しない操作の流れ。回帰テストの対象を決める単位
- 不具合の重要度(Critical / High / Medium / Low、P0〜P3): 起きた問題の深刻さ
- 機能の優先度としての「クリティカル」: 企画で「無いと売れない機能」
回帰テストの対象は CUJ、不具合は重要度、と使い分ける。
本数は先に決めない
「主要な流れを 10 本」と言いかけたが、本数から入るのはやめた。根拠は 2 つから取る。
- コードにある機能の一覧。画面 URL と API の手続きを列挙すれば、候補は漏れなく出る。URL の階層は組織標準で決めてあるので、機能ごとに URL がある。画面のタイトルが画面ごとに変わっているかは要確認(SPA は固定のままのことが多い)
- 実際に使われている量。新しくアクセス解析を入れなくても、Cloud Run のリクエストログに全リクエストの URL が残っているので、パス別・手続き別の件数を集計すれば出る
ただし、公開 1〜2 週間ではログが薄く、テスターの操作が混ざる。使用量を待つのは遠回りになるので、順番はこうした。
- 最初の束: コードの一覧と、数字を待たずに分かる「壊れると致命的な流れ」(ログイン、課金、代理店の紐付け、各製品の主業務 1 往復)から作って回し始める
- 1 か月後: ログの使用量を取り、「よく使われるのに束に無い流れ」を足し、「誰も使わない」ものを外す
使用量は「最初の選定」ではなく「1 か月後の見直し」に使う。
活用プラン
書く(規約)
| 項目 | 決め方 |
|---|---|
| 置き場所 | 各リポジトリの e2e/。回帰の束は e2e/regression/、issue ごとの受け入れは e2e/acceptance/<issue番号>/。クローズ時に regression へ移す |
| 1 本の単位 | 1 つの CUJ = 1 ファイル。前提データはテスト内で作り、他のテストに依存しない |
| ロケーター | 役割とラベルで指す(getByRole、getByLabel)。CSS のクラス名や DOM 構造で指さない |
| 待ち方 | sleep 禁止。web-first assertion(要素が現れるまで自動で待つ)だけ |
| データ | 製品ごとにデモ店舗・デモ会員を固定 ID で用意し、テストは自分の店舗だけを触る。共有 DB でも PR 同士がぶつからない |
| 外部連携 | 決済・Google・LINE は CI ではモック。実挙動は本番か Sandbox で別途 |
| 証跡 | 失敗時は trace とスクリーンショットを自動保存し PR に添付。受け入れの画像証跡もこの仕組みで撮る |
走らせる(どこで、いつ)
| 場面 | 何を | 環境 | 合否 |
|---|---|---|---|
| PR を開く・push するたび | 単体 + e2e/regression/ 全部 |
CI の使い捨て MySQL | 赤ならマージ不可 |
| 受け入れ | e2e/acceptance/<issue>/ |
同上 + プレビュー環境で目視 | 受け入れ条件の一部 |
| ステージング(ラベル付き PR) | スモーク数本 | STG の pr-N URL | 参考。migration の PR は必須 |
| 本番デプロイ直後 | スモーク数本、読み取りだけ | 本番 | 赤なら通知 |
保つ(運用)
- flaky: 原因なく 2 回赤になったら「隔離」ラベルで一時的に束から外し、1 週間以内に修正か削除。skip のまま放置しない。件数を月次で記録
- 束を育てる責務: 各プロジェクトの PM。issue クローズ時に受け入れテストを regression へ移す。月次で「本数、失敗数、拾った退行の数」を記録
- 見直し: 1 か月後にログの使用量で過不足を調整
製品ごとの着手
| 製品 | 現在地 | 最初の作業 |
|---|---|---|
| A(先行) | Playwright + ローカル MySQL の CI あり | e2e/regression/ を作り、既存の受け入れテストから移す。ラベル起動のプレビュー環境 |
| B | E2E 基盤なし | CI の使い捨て DB 基盤を A から移植(2〜3 日)。最初の束はログイン・外部連携・投稿・代理店紐付け |
| C | 基盤なし、ブランチ運用の整理待ち | 整理後に B と同じ手順 |
一番重い部分
B と C に「CI の使い捨て DB 基盤」を作る工数。A の基盤(MySQL を非標準ポートで起動する方式)が移植できる前提で 2〜3 日と見ているが、ORM の構成が違うので同じに動くかは未検証。ここが最初の山。
自分への注意
- 「決めない」を「始めない」にしない。本数は結果として決まる
- 回帰テストは「前に壊れたところを二度と壊さない」ための束。新しい壊れ方はテスターと監視が拾う。この分担を崩さない
- 「特に効く 2 つ」と言った瞬間に、他の 8 つを捨てたように聞こえる。役割が違うものは並べて言う