1. やろうとしたこと
AI による効率化を実際に試すことが目的に含まれたプロジェクトに参加しました。Vue2 で動いていた業務アプリを React へ移行する案件で、私は移行後の検証を担当していました。
見た目の等価性は VRT(ビジュアルリグレッションテスト)で機械化できました。その話は別記事に書いています。
残ったのが振る舞いの検証、つまり E2E テストです。ここで私は、全部自動化しようとしました。
構想はこうです。
- テナント名を指定する
- シナリオが生成される
- 各画面のテスト観点が洗い出される
- Playwright のテストコードが生成される
- テストが実行される
- テスト結果報告書が出力される
テナント名を渡せば報告書まで出る。人間は結果を見るだけ。そういう絵を描いていました。
結論から言うと、この構想は捨てました。 そして捨てるまでに、それなりの時間を使いました。
2. 全自動にするには、毎回同じ結果が出る必要がある
パイプラインを組むにあたって、最初に必要だと考えたのが再現性でした。
テナント名を渡せば報告書まで出る形にするなら、何度回しても同じ状態に落ち着く、いわば冪等な形になっている必要があります。
ただし、生成物そのものが一字一句同じである必要はありません。テストコードの書き方や報告書の文面が多少変わっても構わない。固定されていなければならないのは、何を確認するかという観点と、どこまでを合格とするかの基準です。実行するたびにこの物差しが変われば、回すたびに別の検証をしていることになります。
ところが最初の構想では、その物差しまで AI に生成させていました。
そして、それが担保できませんでした。
3. 同じ画面から、毎回違う観点が出てくる
崩れたのは、パイプラインの3番目です。テスト観点の洗い出しでした。
画面を渡して「この画面で確認すべきことを列挙してください」と指示すると、それらしい観点が返ってきます。内容も悪くありません。問題は、同じ画面を渡しても毎回違う観点が出てくることでした。
共通仕様であるはずの同じ画面について、あるときは20個、あるときは17個。しかも中身が完全には重なりません。テナント固有の仕様差によるものではなく、生成のたびに揺れていました。
これは致命的でした。今回証明したいのは新旧の等価性なので、新旧・テナント間で同じ物差しを当てることが前提になります。物差しが毎回変わるなら、比較そのものが成立しません。
さらに、どのテナントで何を確認したのかが再現できません。報告書を出しても、その報告書が何を保証しているのか説明できない。検証としては成り立ちません。
プロンプトの書き方を変え、渡す情報を増やし、出力形式を細かく指定しました。ばらつきは小さくなりますが、無くなりません。そもそも生成の揺らぎを工夫で消そうとしていること自体が、筋の悪い方向でした。
4. 原因は AI ではなく、私でした
ここで正直に書いておきます。
うまくいかなかった原因は、AI の性能ではありませんでした。私が「全自動化」にこだわりすぎたことです。
工程を1から6まで並べて、全部つながったら気持ちがいい。テナント名を入れたら報告書が出てくる絵が、自分の中で先にできていました。だから、うまくいかない部分に対して「どうすれば AI にやらせられるか」だけを考えていました。
「そもそも、ここは AI にやらせるべきなのか」を考えていませんでした。
構想が先にあると、失敗の解釈がそれに引きずられます。観点の生成が安定しないという事実に対して、私が出した答えは「プロンプトを工夫する」でした。実際には、それは工夫で埋まる問題ではありませんでした。
5. 答えを出したのはチームのメンバーでした
行き詰まっていたときに、同じチームのメンバーから出た案がこれです。
観点とシナリオは人間が固定する。基準となる1テナント分だけ人間が作って、あとはそれに揃えて AI に作らせる。
聞いた瞬間に、自分がこだわっていたものが何だったのかが分かりました。
全自動化を諦めるということは、工程が途中で人間に戻るということです。それが嫌で避けていました。しかし実際にやってみると、人間が担当するのは6工程のうち1つだけでした。基準となる1テナント分の観点とシナリオを確定すれば、残りのテナントは基準を維持したまま AI に展開させられます。
そして、この形は VRT と似た構造をしています。VRT は旧のスクリーンショットという実際の出力を基準にし、こちらは人間が確定したテスト仕様を基準にするので、対象は違います。ただし、先に基準を固定して、そこからの逸脱を見るという点では同じです。基準そのものを毎回生成していたのが間違いだったわけです。
自分では気づけませんでした。構想を持っていた本人が、その構想の外側を見るのは難しいと思います。
6. なぜ、観点だけは人間なのか
結果として、役割分担はこうなりました。
- シナリオとテスト観点 ― 人間と AI で作成。抜け漏れのチェックは人間が持つ
- Playwright のコード ― Claude Code が生成、Codex がレビュー、その結果を人間が確認
境界の引き方には理屈があります。
観点の欠落は、実行結果からは発見できません。存在しないテストは失敗しないからです。 20個あるべき観点が17個しかなくても、その17個は全部通ります。レポートは緑色になります。何も起きません。
一方、コードの側は事情が違います。構文エラーや操作の失敗であれば、実行時に比較的表面化します。落ちれば気づきます。
つまり、間違いが自分から現れる領域と、間違いが黙って消える領域がある。 後者を人間が持つ、というのが分担の基準になりました。
ただし、これで安全になったわけではありません。誤った対象を見ているテストや、常に真になるアサーションは、動いても間違っています。コード生成を AI に任せられることと、そのコードが正しい検証になっていることは別です。 だから生成時とは別のモデルをレビューに使い、同じ推論の癖による見落としが重なる可能性を下げています。ただし、別モデルのレビューも正しさを保証するものではありません。最終的には、観点と実行結果が対応しているかを人間が確認します。
7. AI を知らない相手にデモした
しばらくして、上位の責任者から声をかけられました。AI についてはほとんど知識がない方です。
AI でどんなことやってますか?
説明しようと思えば、いくらでも説明できる状態でした。役割分担の設計、観点を固定した理由、レビューを別モデルにやらせている意図。しかし相手に前提知識がありません。
なので、説明せずに動かして見せました。1テナント分の E2E テストが、生成から実行、報告書の出力まで通るところをそのままデモしました。
かなり驚かれた様子で、その後、他のプロジェクトのメンバーにも見に行くよう声がかかったと聞きました。
8. 伝わったのは、人手の工程が見えなかったからだと思う
後から考えると、伝わった理由ははっきりしています。
見せたのが「速くなった」ではなく「工程がまるごと無くなったように見える」状態だったからです。
デモでは、すでに人間が確定した観点とシナリオを入力として使っていました。その準備工程は画面上に現れません。見る側には、テストの生成から実行、報告書の出力までが一本の流れとして走っているように見えます。
テストを書く速度が2倍になりました、と言われても、AI を知らない人には評価のしようがありません。もともとどれくらいかかるのか分からないからです。しかし、これまで人がやっていた工程が画面上で勝手に流れていけば、前提知識がなくても違いが分かります。
そして、これは説明では代替できません。仕組みを丁寧に話すほど、相手は理解の負荷を感じます。動くものを見せるほうが速い。
ただし、ここには落とし穴もありました。
9. 「全部自動化した」とは言えない
デモの場で、私は自動化した部分を全自動のように見せていました。実際には、観点とシナリオは人間が作っています。そこが一番手間のかかる部分です。
嘘をついたわけではありませんが、正確でもありませんでした。正確に伝えると伝わりにくく、伝わりやすく言うと正確でなくなる。 ここにはトレードオフが実在します。
問題は、他プロジェクトへ展開する話が出ていることです。見た人が「観点も含めて全自動で回る」と理解したまま自分のところへ持ち帰ると、必ず躓きます。そして躓いたときに、デモそのものの信用が落ちます。
デモで関心を引くことと、他人が移植できる形にすることは、別の作業です。前者は動くものを見せれば済みますが、後者は何が自動で何が人手かを正確に伝えないと成立しません。
他プロジェクトへ展開される前に、自動化できた範囲と人間が担う範囲を明示した説明に改めるつもりです。
10. まとめ
- E2E テスト工程の全自動化を目指して、テスト観点の生成が再現できず断念した
- 原因は AI の性能ではなく、全自動化にこだわった自分の思い込みだった
- 解決策はチームのメンバーから出た。観点とシナリオを人間が1パターン固定し、残りを AI に揃えさせる
- 人間が持つべきは「間違いが黙って消える領域」。観点の欠落は実行結果に現れない
- AI を知らない相手には、仕組みの説明より工程が消えている状態を見せるほうが伝わる
- ただし、伝わりやすさと正確さは別なので、展開するときは言い直す必要がある
AI にどこまで任せるかの線引きは、技術の問題だと思っていました。実際には、自分が描いた絵をどこで捨てられるかの問題でした。
構想を持っている本人が、その構想の外側を見るのは難しい。今回それを教えてくれたのは AI ではなく、隣にいた人でした。