ANTIGRAVITY LABEN
記事一覧/アプリ開発
アプリ開発/2026-06-30上級

Antigravity が書いたテストが全部グリーンなのに同じバグが再発するとき — 空回りするアサーションを計測する運用メモ

AI に書かせたテストがすべて通り、カバレッジも高いのに本番で同じ不具合が戻ってくる。原因はモック過多とトートロジー的なアサーションです。ミューテーションテストを正解とし、テストが実際に何を守っているかを実測して運用で立て直すメモです。

antigravity404app-dev42testing14mutation-testingvitest2strykerci-cd12

プレミアム記事

緑のテストが守ってくれなかった朝

ある修正をリリースした数日後、以前直したはずの不具合が同じ形で戻ってきたことがあります。テストは全部グリーン、カバレッジレポートも 90% 台。なのに、本番では割引計算が税抜き価格に対してかかってしまっていました。手元でテストを走らせ直しても、やはり全部通ります。

調べていくと、原因はテストの本数でもカバレッジの数字でもありませんでした。Antigravity のエージェントに「この関数のテストを書いて」と頼んで生成されたテスト群が、コードを通過はしているのに、肝心の振る舞いを一つも検証していなかったのです。実行はされる、だから行カバレッジは上がる。けれど、ロジックが間違っていても誰も気づけない。テストが「実行された」ことと「検証している」ことは別物だ、という当たり前を、回帰バグの形で突きつけられました。

この記事は、AI に書かせたテストが静かに空回りする現象を、ミューテーションテストという物差しで可視化し、運用で立て直すための実務メモです。題材は Vitest と Stryker Mutator ですが、考え方は Jest でも同じです。

なぜ AI 生成テストは「通るのに守らない」のか

エージェントは、与えられたコードを読み、それを通すテストを生成します。ここに落とし穴があります。「通すテスト」を最短で作ろうとすると、振る舞いを固定するのではなく、現状の出力をそのまま追認するテストになりがちなのです。私が繰り返し踏んだのは、次の3類型でした。

類型症状なぜ回帰を止められないか
モック過多依存をすべてモックし、戻り値も固定するテストしているのが実装ではなくモックの設定値になり、本物のロジックを一行も通らない
トートロジーexpect(result).toBe(result) 的に、計算結果をそのまま期待値に流用実装が間違っても期待値も一緒に間違うので、永遠に一致する
スナップショット追認初回出力をスナップショットとして固定し、以後それと比較誤った出力をそのまま正解として焼き付けてしまう

トートロジーは特に見つけにくいものです。例えば割引関数のテストで、エージェントが次のように書くことがあります。

import { describe, it, expect } from 'vitest'
import { applyDiscount } from '../src/cart/discount'
 
it('割引が適用される', () => {
  const price = 1000
  const rate = 0.1
  // ❌ 期待値を実装と同じ式で計算している(空回り)
  const expected = price - price * rate
  expect(applyDiscount(price, rate)).toBe(expected)
})

このテストは緑になります。しかし applyDiscount の中身が税抜きに対して割引をかけていようが、税込みにかけていようが、expected を同じ式で算出している限り常に一致します。検証しているのは「同じ式を二回書いたら同じ答えになる」という事実だけで、仕様は一文字も守っていません。正しくはこう書くべきでした。

it('税抜き価格に対して10%割引が適用される', () => {
  // ✅ 期待値は実装に依存しないリテラルで固定する
  expect(applyDiscount(1000, 0.1)).toBe(900)
})
 
it('割引率0で価格が変わらない', () => {
  expect(applyDiscount(1000, 0)).toBe(1000)
})
 
it('割引率1で価格が0になる', () => {
  expect(applyDiscount(1000, 1)).toBe(0)
})

期待値を実装の式から切り離し、人間が手計算した定数で固定する。これだけで、ロジックがずれた瞬間にテストが赤くなります。AI に任せるときも、この「期待値はリテラルで」という制約を最初に渡すかどうかで結果が大きく変わります。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
行カバレッジ90%でもミューテーションスコアが低い『カバレッジ劇場』を、Stryker の survived mutant から特定する手順
AI 生成テストが空回りする3類型(モック過多・トートロジー・スナップショット追認)を見分けるアサーション監査の具体策
変更ファイルだけにミューテーションスコア閾値をかけ、CI を遅くせずに回帰を止める実装パターン
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

Agents & Manager2026-04-16
Antigravity エージェントでテストパイプラインを自動構築する:品質保証を AI に任せる実践設計
Antigravity の AI エージェントを活用して、単体テスト・統合テスト・E2E テストを自動生成・自動実行するパイプラインを本番品質で構築する方法を、実装コードとともに解説します。
アプリ開発2026-06-28
メディエーションを増やしたら iOS の計測が静かに痩せた — SKAdNetwork ID のズレを4アプリで揃える
メディエーションに新しいパートナーを足したのに iOS の収益が伸びず、SKAdNetwork ID の登録漏れが原因だった実体験。Info.plist の SKAdNetworkItems を4アプリで突き合わせ、Antigravity エージェントに照合させて人間が採否を決める運用を紹介します。
アプリ開発2026-06-25
「広告を見たら壁紙を解放」をエージェントがクライアント側だけで付与していた — リワード報酬をSSVで検証し直した記録
リワード広告を見たら壁紙を解放する機能を Antigravity のエージェントに頼んだら、解放フラグをクライアント側だけで書き込む実装が返ってきました。なぜそれでは足りないのか、AdMob のサーバーサイド検証(SSV)で報酬付与を検証し直し、二重付与まで止めた設計を記録します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →