同じ仕様書でブロック崩しを2つ作らせて、片方(Codex 版)を検査していたときの話です。
list_tests を叩くと PlayMode テストが5件見えます。実行します。エラーは出ません。警告も出ません。そして結果が0件でした。
5件
一覧に見えるテスト
list_tests の結果
0件
実際に実行された数
ビルド対象が WebGL のとき
0
エラー・警告
なにも出ない
5/5
Standalone に戻すと
同じコードで全部合格
失敗ではありません。0件が0件通ったので、成功扱いです。合格数だけを見ていたら、たぶん気づかずに次へ進んでいました。
何が起きていたか
| Claude Code 版 | Codex 版 | |
|---|---|---|
list_tests で見える PlayMode テスト | 5件 | 5件 |
| ビルド対象 WebGL で実行 | 5/5 合格(2.1秒) | 0件(実行されない) |
| ビルド対象 StandaloneWindows64 で実行 | 5/5 合格 | 5/5 合格(2.14秒) |
コードは関係ありませんでした。テストの中身は両方とも普通に動きます。違っていたのは、テスト用 asmdef の書き方だけです。
⚠️ 0件は「緑」に見える
テストが1件も実行されなくても、失敗件数は0です。CI でも、AI の報告でも、「エラーなし」と表示されます。合格したかどうかではなく、何件実行されたかを見てください。
原因:asmdef の古い書き方
2つのプロジェクトの PlayMode テスト用 asmdef を並べます(違いのある行だけ)。
動かなかったほう(Codex 版)
{
"name": "Breakout.PlayModeTests",
"references": [
"Breakout.Core",
"Breakout.Runtime"
],
"optionalUnityReferences": [
"TestAssemblies"
]
}動いたほう(Claude Code 版)
{
"name": "Breakout.Tests.PlayMode",
"references": [
"Breakout.Core",
"Breakout.Runtime",
"UnityEngine.TestRunner",
"UnityEditor.TestRunner"
],
"overrideReferences": true,
"precompiledReferences": ["nunit.framework.dll"],
"autoReferenced": false,
"defineConstraints": ["UNITY_INCLUDE_TESTS"]
}optionalUnityReferences: ["TestAssemblies"] は昔の書き方です。今の Unity が Test Framework 経由で Test Assembly を作ると、上の長いほうが生成されます。決め手は3つ。
手順 01
overrideReferences: true
参照を自分で決めると宣言する
手順 02
precompiledReferences
nunit.framework.dll を明示する
手順 03
defineConstraints
UNITY_INCLUDE_TESTS のときだけ作る
古い書き方でも Standalone では動いてしまうので、普段は気づけません。 ビルド対象を WebGL に切り替えたまま作業していると、そこではじめて黙って0件になります。
なぜ WebGL のときだけ起きるのか
references に UnityEngine.TestRunner も UnityEditor.TestRunner も書かれておらず、defineConstraints も無いので、このアセンブリを「現在のビルド対象向けにコンパイルする理由」が Unity 側に伝わりません。Standalone のときはたまたま解決できていたものが、WebGL に切り替えた瞬間に解決できなくなった、という形です。
list_tests が5件を返し続けたのは、一覧がソース側を見ているからです。一覧に出ることと、実行できることは別物でした。
直し方
メニューの Assets > Create > Testing > Test Assembly Folder で作り直すのが確実です(Test Runner ウィンドウからも作れます)。手で直す場合は、既存の asmdef に次を足します。
{
"references": ["UnityEngine.TestRunner", "UnityEditor.TestRunner"],
"overrideReferences": true,
"precompiledReferences": ["nunit.framework.dll"],
"autoReferenced": false,
"defineConstraints": ["UNITY_INCLUDE_TESTS"]
}
optionalUnityReferences は消してかまいません。
直したあとは、ビルド対象を実際の公開先(WebGL など)に切り替えた状態でもう一度実行してください。Standalone で通っても意味がありません。
AI に任せるときのチェック
AI エージェントは「テストは全部通りました」と報告してきます。嘘ではありません。0件が0件通っているので、本人の中では正しい報告です。
報告をそのまま受け取る
件数で受け取る
passed と total が、期待した件数(今回なら5)と合っているかを見るだから見るのは件数です。Unity CLI なら結果が Temp/pipeline_test_status.json に書かれるので、そこを読みます。
unity command run_tests --mode PlayMode --async_tests true
# 完了後に Temp/pipeline_test_status.json の passed / total を確認する
件数は仕様書に書いておく
「PlayMode テストを5件以上」と仕様書に書いておくと、実行件数が期待値と合っているかを機械的に判定できます。「テストを書いて通すこと」だけだと、0件でも条件を満たしてしまいます。
まとめ
- テストが0件でも失敗にはならない。緑に見えるので一番気づきにくい
- 原因はテスト用 asmdef の古い書き方。
overrideReferences/precompiledReferences/defineConstraintsが要る - 古い書き方は Standalone では動く。WebGL に切り替えたときだけ落ちるので、切り替えた状態で必ず確認する
- AI の報告は「合格」ではなく「実行件数」で受け取る