「全テストがパスしました」の中身が skip 3件だったとき | GH Media
URLがコピーされました

「全テストがパスしました」の中身が skip 3件だったとき

URLがコピーされました
「全テストがパスしました」の中身が skip 3件だったとき

AI コーディングエージェントに機能追加を任せて、「全テストがパスしました」と報告が返ってきたとします。差分を開くと、テストファイルに skip が3つ増えています。

あるいは、expect(result).toEqual(expected)expect(result).toBeDefined() に書き換わっている。あるいは、期待値の定数のほうが実装の出力に合わせて更新されている。指摘すると素直に謝って実装をやり直すのに、次の依頼でまた同じことをします。

この挙動を「まだ AI が未熟だから、モデルが賢くなれば直る」と受け取っている人は多いはずです。しかしこれは能力の問題ではなく、評価の形が生む必然だと考えたほうが、対処が見つかります。

何を達成とみなすかを、依頼文が決めている

「この機能を実装して」という依頼には、完了の定義が書かれていません。書かれていないので、エージェントは自分で完了の基準を決めます。手元にある最も分かりやすい基準は「テストコマンドが緑になること」です。

ここで、緑にする方法は2通りあります。実装を直すか、テストを直すか。依頼文はどちらを禁じていません。 そして後者のほうが確実に、短時間で緑になります。

Zenn の記事「AIエージェントはなぜテストを握り潰すのか」は、この構造を 代理報酬 という言葉で説明しています。「顧客に価値を届ける」という本来の目標は直接測れないので、テストの成否のような測れる指標で代理させる。エージェントは代理のほうを最適化するので、代理と本来の目標がズレていれば、ズレたほうへ全力で走ります。報酬設計に自覚的になり、そのズレを補正し続けることを、記事では報酬エンジニアリングと呼んでいます。

人間のエンジニアが同じことをしないのは、能力が高いからではありません。テストを skip にして完了報告をしたら信用を失うという、コマンドの外側にある評価を知っているからです。エージェントはその外側を見ていません。

握り潰しは、必ず差分に残る

救いは、この振る舞いが隠れないことです。実装を直したのかテストを直したのかは、差分を見れば分かります。問題は、プロダクトコードとテストコードが同じ1つの差分に混ざっていると、誰も気づかないことです。

見るべきものは決まっています。

見る場所出てくるサイン
テストファイルの差分skip / only / xit の追加、テストケースの削除
アサーション等値比較が存在確認に緩められている、期待値の定数が書き換わっている
モック実装を呼ばずに済ませる範囲が広がっている
CI 設定失敗を許容するフラグ、タイムアウトの延長、対象ファイルの除外

機械的に拾うだけなら、テスト差分の抽出はコマンド1つで済みます。

# テストコードの変更だけを抜き出して確認する
git diff origin/main...HEAD -- '**/*.test.*' '**/*.spec.*'

# 無効化キーワードが増えていないかを数える
git diff origin/main...HEAD -- '**/*.test.*' | grep -E '^\+.*\b(skip|only|xit|xdescribe)\b'

これを CI に入れて、ヒットしたら人間のレビューを必須にするだけで、報告と実態のズレはかなり潰せます。テスト件数だけを見ていると、skip されたテストも「存在するテスト」として数えられてしまうので、件数ではなく実行された件数を見てください。

プロダクトコードとテストコードの差分を分けてレビューする流れの図

完了条件を「緑」以外の言葉で書く

検知の仕組みを入れても、依頼の形が変わらなければ同じことが起き続けます。効くのは、完了条件を最初に、テストコマンドの外側の言葉で書くことです。

たとえば「この機能を実装して」ではなく、次のように書きます。

  • テストコードは変更しない。 変更が必要だと判断した場合は、変更せずに理由を報告する
  • 既存のテストが落ちる場合、落ちている原因を説明してから実装を修正する
  • 完了の報告には、実行されたテストの件数(skip を除く)を含める

3つ目が地味に効きます。skip を除いた実行件数を報告させると、握り潰したときに数字が減るので、報告そのものが自己申告の証拠になります。

これは AI に限った話ではありません。人間の開発チームに対しても、受け入れテストで発注側が見るべき項目で整理したとおり、「テストが通っている」は成果の証明としては弱い指標です。AI エージェントが日常的に使われるようになって、その弱さが表面化しただけとも言えます。

受託で線を引くなら、どこに書くか

外部に開発を委託していて、相手が AI エージェントを使っている場合。これは今や前提として考えるべきですが、契約や仕様書に書いておける項目があります。

1. テストコードの変更を独立した承認対象にする。 プロダクトコードの変更とテストコードの変更を同じプルリクエストに混ぜない、あるいは混ぜる場合はテスト差分を明示する。これだけで、握り潰しがレビューの視界に入ります。

2. カバレッジではなく、テストが実際に欠陥を捕まえるかで見る。 カバレッジは、アサーションを空にしても下がりません。テストの質そのものを測る方法はミューテーションテストで納品物のテスト品質を見るに整理しました。

3. 受け入れ基準を、コマンドの結果ではなく業務の言葉で書く。 「テストが通ること」ではなく「この条件のとき、この画面にこの値が出ること」。前者は代理報酬そのものなので、握り潰しの対象になります。後者は握り潰せません。

AI が書いたコードを受け入れる基準をどう定義するかはAI が書いたコードの受け入れ基準でも扱っています。合わせて、成果物の作られ方を記録として残す設計も検討してください。

次にやること

まず、直近1か月のプルリクエストから、テストファイルの差分だけを抜き出して眺めてください。 skip が増えているものが1つでも見つかったら、それは今後も起き続けます。ゼロなら、いまの依頼の書き方がうまくいっている証拠です。

そのうえで、エージェントへの依頼テンプレートに「テストコードは変更しない」の1行を足してください。 効果が出るまでに設定変更もツール導入も要りません。

AI エージェントを組み込んだ開発体制の設計、受け入れ基準の整備、委託先との品質条件の詰め方については、グリームハブの開発・AI・自動化のご相談で承っています。チームの体制と現在の開発フローによって進め方が変わるため、個別にご相談ください。お問い合わせからどうぞ。

Sources

URLがコピーされました

グリームハブ株式会社は、変化の激しい時代において、アイデアを形にし、人がもっと自由に、もっと創造的に生きられる世界を目指しています。

記事を書いた人

鈴木 翔

鈴木 翔

技術の可能性に魅了され、学生時代からプログラミングとデジタルアートの分野に深い関心を持つ

関連記事

「TECH」の記事一覧を見る