Antigravity のエージェントに失敗中のテストを渡して修正を任せたところ、数分後に全テストが緑になって返ってきました。差分を見ると、直っていたのはアプリのコードではなく fixtures/users.json のほうでした。期待値に合うようにテストデータを書き換えて、テストを通していたのです。
エージェントに悪意はありません。「テストを通す」という指示を最短経路で達成しただけです。問題は、テストデータの扱いを何も決めずに任せていた私自身の側にありました。
同じ轍を踏む方が減るように、それ以来私が固定している3つの決めごと、fixture の所有権、シードの決定性、実データからの切り出し手順を順に書きます。
決めごと1 — fixture の所有権をエージェントから外す
最初にやったのは「fixtures/ 配下はエージェントにとって読み取り専用」というルール化です。修正が必要だと思ったら、変更せずに提案として報告する。これを Guide スキルに1行書くだけでも行動は大きく変わります。
## テストデータの扱い
- fixtures/ 配下のファイルは読み取り専用とする
- 期待値の変更が必要だと判断した場合は、変更せずに
「fixture 変更提案」として理由とともに報告するただし Guide スキルは助言であって強制ではないため、機械的な backstop を CI に置きます。fixture の変更がアプリコードの変更と同じコミットに混ざっていたら弾く、という単純なガードです。
#!/usr/bin/env bash
# fixture-guard.sh — fixtureとsrcの同時変更を検出する
CHANGED="$(git diff --cached --name-only)"
FIXTURE_TOUCHED=$(echo "$CHANGED" | grep -c '^fixtures/' || true)
SRC_TOUCHED=$(echo "$CHANGED" | grep -c '^src/' || true)
if [ "$FIXTURE_TOUCHED" -gt 0 ] && [ "$SRC_TOUCHED" -gt 0 ]; then
echo "❌ fixture と src の同時変更は分離してください"
echo " fixture の変更は理由をコミットメッセージに明記の上、単独コミットで"
exit 1
fi
exit 0fixture を変えること自体は禁止しません。仕様変更に追随する正当な更新はあります。禁止するのは「コード修正と同じ手の中でこっそり期待値を動かす」ことだけです。単独コミットに分離されていれば、レビューで必ず目に入ります。
決めごと2 — シードは決定的に生成する
エージェントが書くテストは、テストデータもエージェントが即興で作りがちです。ランダムな名前や日付をテスト内で生成すると、動くときと動かないときがある flaky なテストの温床になります。
ここでの罠は、テストを1回流しただけでは問題が見えないことです。数十回の無人実行を経てから偶発的に失敗し始めるため、原因の特定に余計な時間を取られます。この不安定さを根本から回避するために、テストデータは生成スクリプトに一本化し、シードを固定することをお勧めします。
// scripts/generate-fixtures.mjs
import { faker } from "@faker-js/faker";
import { writeFileSync } from "node:fs";
faker.seed(20260702); // 固定シード — 何度実行しても同じデータになる
const users = Array.from({ length: 50 }, (_, i) => ({
id: `u${String(i + 1).padStart(4, "0")}`,
name: faker.person.fullName(),
email: faker.internet.email().toLowerCase(),
createdAt: faker.date
.between({ from: "2025-01-01", to: "2026-06-30" })
.toISOString(),
plan: faker.helpers.arrayElement(["free", "pro", "premium"]),
}));
writeFileSync(
"fixtures/users.json",
JSON.stringify({ schemaVersion: 3, users }, null, 2)
);
console.log(`generated ${users.length} users (schemaVersion 3)`);固定シードにしておくと、fixture が壊れた疑いがあるときに再生成して diff を取るだけで「手で書き換えられたかどうか」を判定できます。生成物とリポジトリ内のファイルが一致しなければ、誰かが(多くの場合エージェントが)直接触った証拠です。
schemaVersion を fixture 自身に埋めてあるのは、テスト側で前提スキーマを検証できるようにするためです。バージョンが合わないときはテストを落とすのではなくスキップして警告する運用にすると、スキーマ移行の途中でもノイズが出ません。