The Unity agent plugin lets coding agents edit scripts, scenes and assets. The step agents skip is proving the C# still works, and Unity's exit code makes that easy to get wrong. With -runTests, Unity exits 0 when every test passed and also when no tests ran at all, for example when a -testFilter matches nothing or the test assembly is missing. 3 means a run error, usually a compile error, and 4 a missing platform.
This loadout adds the testing half for Unity 6 projects. The rules keep logic in plain C# classes so Edit Mode tests cover it in milliseconds, with a test .asmdef and an example NUnit test to copy. A standard-library Python wrapper runs the Editor in batch mode with the documented flags, deletes stale results first, and reads the NUnit 3 XML. It lists each failure with its message and first stack line, pulls C# compile errors and the "project already open" case out of the log, and treats zero tests as a failure. The verifier drives it with a stub Editor that writes each outcome Unity documents.
What's in it
- Zero tests ran = failure, even though Unity exits 0
- Exit codes 0/2/3/4 explained; compile errors pulled from the log
- Stale result files deleted before every run
- Edit Mode .asmdef and an NUnit example test to copy
- Plain C# logic, thin MonoBehaviours, so tests run in milliseconds
You'll need
- Tools:
unity-6,python3 - Environment variables:
UNITY_PATH
Verification
| Check | Result | What we found |
|---|---|---|
| Listinglisting.yaml matches the schema and declares every file in the folder. | Pass | Schema valid; 7 files declared, none missing or extra
|
| Files parseJSON parses; SKILL.md and .mdc front matter is valid YAML with the fields each agent needs; code fences are closed. | Pass | All 7 files parse; front matter valid |
| AdaptersCLAUDE.md imports @AGENTS.md, GEMINI.md imports @./AGENTS.md, and both match the generator. | Pass | CLAUDE.md and GEMINI.md import AGENTS.md and are up to date
|
| Install pathsEvery file lands where each agent documents it, with no collisions, and the laid-out project is re-discovered correctly. | Pass | Correct paths for all 6 agents; layouts re-discovered
|
| MCP configmcp.json is structurally valid, converts to each agent's format, declares no literal secrets, and referenced packages exist on npm/PyPI. | Not applicable | No MCP servers in this loadout |
| Safety scanThe intake scanner finds no credentials, risky shell, hidden Unicode, instructions hidden in HTML comments or after long blank padding, or prompt-injection and covert wording (such as telling the agent to keep something from you), and the listing's network flag is honest. | Pass | Clean: no credentials, risky shell, hidden text or covert instructions
|
| ReferencesLinks and file paths between the loadout's files resolve, including for each agent's installed layout. | Pass | 2 references between files resolve for every agent |
| Size limitsFile count and sizes are within the submission limits; SKILL.md bodies stay under 500 lines. | Pass | 7 files, 11.5 KB total; largest skills/unity-tests/scripts/unity_tests.py 4.9 KB
|
| LicenceA recognised SPDX licence, with the licence text available. | Pass | MIT, by SetupBay; text in the repository LICENSE |
| Starter buildA minimal fixture project with the loadout applied installs and builds or type-checks, and the loadout's own code examples compile. | Pass | The unity-tests wrapper runs a stub Unity Editor that writes the NUnit 3 results and log for each documented outcome. It passes a green run, lists a failing test with its message and line, reports a skipped test's reason, fails the zero-tests run that Unity exits 0 on, pulls a C# compile error out o
|
What this means: a script checked the files themselves: they parse, they install where each agent looks, any MCP config is sound, the safety scan is clean, references between files resolve, and, where a free and repeatable fixture exists, a small starter project builds with the loadout applied. No AI agent was run. Per-agent results from agent runs are separate and stay untested until an agent actually runs.
Install
Choose your agent. Run the commands from your project root, or download a zip already laid out in the right folders.
Claude Code reads CLAUDE.md (imports AGENTS.md with @AGENTS.md) and skills from .claude/skills/.
curl -fsSL --create-dirs -o AGENTS.md https://setupbay.com/raw/unity-test-runner/1.0.0/AGENTS.md curl -fsSL --create-dirs -o CLAUDE.md https://setupbay.com/raw/unity-test-runner/1.0.0/CLAUDE.md curl -fsSL --create-dirs -o .claude/skills/unity-tests/SKILL.md https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/SKILL.md curl -fsSL --create-dirs -o .claude/skills/unity-tests/scripts/unity_tests.py https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/scripts/unity_tests.py curl -fsSL --create-dirs -o .claude/skills/unity-tests/references/EditModeTests.asmdef.json https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/references/EditModeTests.asmdef.json curl -fsSL --create-dirs -o .claude/skills/unity-tests/references/HealthTests.cs https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/references/HealthTests.cs
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
CLAUDE.md | CLAUDE.md |
skills/unity-tests/SKILL.md | .claude/skills/unity-tests/SKILL.md |
skills/unity-tests/scripts/unity_tests.py | .claude/skills/unity-tests/scripts/unity_tests.py |
skills/unity-tests/references/EditModeTests.asmdef.json | .claude/skills/unity-tests/references/EditModeTests.asmdef.json |
skills/unity-tests/references/HealthTests.cs | .claude/skills/unity-tests/references/HealthTests.cs |
Already have an AGENTS.md or CLAUDE.md? The commands above overwrite it — download the file instead and merge the sections you want.
Codex CLI reads AGENTS.md and skills from .agents/skills/.
curl -fsSL --create-dirs -o AGENTS.md https://setupbay.com/raw/unity-test-runner/1.0.0/AGENTS.md curl -fsSL --create-dirs -o .agents/skills/unity-tests/SKILL.md https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/SKILL.md curl -fsSL --create-dirs -o .agents/skills/unity-tests/scripts/unity_tests.py https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/scripts/unity_tests.py curl -fsSL --create-dirs -o .agents/skills/unity-tests/references/EditModeTests.asmdef.json https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/references/EditModeTests.asmdef.json curl -fsSL --create-dirs -o .agents/skills/unity-tests/references/HealthTests.cs https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/references/HealthTests.cs
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
skills/unity-tests/SKILL.md | .agents/skills/unity-tests/SKILL.md |
skills/unity-tests/scripts/unity_tests.py | .agents/skills/unity-tests/scripts/unity_tests.py |
skills/unity-tests/references/EditModeTests.asmdef.json | .agents/skills/unity-tests/references/EditModeTests.asmdef.json |
skills/unity-tests/references/HealthTests.cs | .agents/skills/unity-tests/references/HealthTests.cs |
Already have an AGENTS.md or CLAUDE.md? The commands above overwrite it — download the file instead and merge the sections you want.
Cursor reads AGENTS.md + .cursor/rules/*.mdc and skills from .agents/skills/.
curl -fsSL --create-dirs -o AGENTS.md https://setupbay.com/raw/unity-test-runner/1.0.0/AGENTS.md curl -fsSL --create-dirs -o .agents/skills/unity-tests/SKILL.md https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/SKILL.md curl -fsSL --create-dirs -o .agents/skills/unity-tests/scripts/unity_tests.py https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/scripts/unity_tests.py curl -fsSL --create-dirs -o .agents/skills/unity-tests/references/EditModeTests.asmdef.json https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/references/EditModeTests.asmdef.json curl -fsSL --create-dirs -o .agents/skills/unity-tests/references/HealthTests.cs https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/references/HealthTests.cs
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
skills/unity-tests/SKILL.md | .agents/skills/unity-tests/SKILL.md |
skills/unity-tests/scripts/unity_tests.py | .agents/skills/unity-tests/scripts/unity_tests.py |
skills/unity-tests/references/EditModeTests.asmdef.json | .agents/skills/unity-tests/references/EditModeTests.asmdef.json |
skills/unity-tests/references/HealthTests.cs | .agents/skills/unity-tests/references/HealthTests.cs |
Already have an AGENTS.md or CLAUDE.md? The commands above overwrite it — download the file instead and merge the sections you want.
Gemini CLI reads GEMINI.md (imports AGENTS.md with @./AGENTS.md) and skills from .agents/skills/.
curl -fsSL --create-dirs -o AGENTS.md https://setupbay.com/raw/unity-test-runner/1.0.0/AGENTS.md curl -fsSL --create-dirs -o GEMINI.md https://setupbay.com/raw/unity-test-runner/1.0.0/GEMINI.md curl -fsSL --create-dirs -o .agents/skills/unity-tests/SKILL.md https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/SKILL.md curl -fsSL --create-dirs -o .agents/skills/unity-tests/scripts/unity_tests.py https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/scripts/unity_tests.py curl -fsSL --create-dirs -o .agents/skills/unity-tests/references/EditModeTests.asmdef.json https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/references/EditModeTests.asmdef.json curl -fsSL --create-dirs -o .agents/skills/unity-tests/references/HealthTests.cs https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/references/HealthTests.cs
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
GEMINI.md | GEMINI.md |
skills/unity-tests/SKILL.md | .agents/skills/unity-tests/SKILL.md |
skills/unity-tests/scripts/unity_tests.py | .agents/skills/unity-tests/scripts/unity_tests.py |
skills/unity-tests/references/EditModeTests.asmdef.json | .agents/skills/unity-tests/references/EditModeTests.asmdef.json |
skills/unity-tests/references/HealthTests.cs | .agents/skills/unity-tests/references/HealthTests.cs |
Already have an AGENTS.md or CLAUDE.md? The commands above overwrite it — download the file instead and merge the sections you want.
Antigravity CLI reads AGENTS.md (read natively; GEMINI.md is also read) and skills from .agents/skills/.
curl -fsSL --create-dirs -o AGENTS.md https://setupbay.com/raw/unity-test-runner/1.0.0/AGENTS.md curl -fsSL --create-dirs -o .agents/skills/unity-tests/SKILL.md https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/SKILL.md curl -fsSL --create-dirs -o .agents/skills/unity-tests/scripts/unity_tests.py https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/scripts/unity_tests.py curl -fsSL --create-dirs -o .agents/skills/unity-tests/references/EditModeTests.asmdef.json https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/references/EditModeTests.asmdef.json curl -fsSL --create-dirs -o .agents/skills/unity-tests/references/HealthTests.cs https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/references/HealthTests.cs
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
skills/unity-tests/SKILL.md | .agents/skills/unity-tests/SKILL.md |
skills/unity-tests/scripts/unity_tests.py | .agents/skills/unity-tests/scripts/unity_tests.py |
skills/unity-tests/references/EditModeTests.asmdef.json | .agents/skills/unity-tests/references/EditModeTests.asmdef.json |
skills/unity-tests/references/HealthTests.cs | .agents/skills/unity-tests/references/HealthTests.cs |
Already have an AGENTS.md or CLAUDE.md? The commands above overwrite it — download the file instead and merge the sections you want.
GitHub Copilot reads AGENTS.md and skills from .agents/skills/.
curl -fsSL --create-dirs -o AGENTS.md https://setupbay.com/raw/unity-test-runner/1.0.0/AGENTS.md curl -fsSL --create-dirs -o .agents/skills/unity-tests/SKILL.md https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/SKILL.md curl -fsSL --create-dirs -o .agents/skills/unity-tests/scripts/unity_tests.py https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/scripts/unity_tests.py curl -fsSL --create-dirs -o .agents/skills/unity-tests/references/EditModeTests.asmdef.json https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/references/EditModeTests.asmdef.json curl -fsSL --create-dirs -o .agents/skills/unity-tests/references/HealthTests.cs https://setupbay.com/raw/unity-test-runner/1.0.0/skills/unity-tests/references/HealthTests.cs
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
skills/unity-tests/SKILL.md | .agents/skills/unity-tests/SKILL.md |
skills/unity-tests/scripts/unity_tests.py | .agents/skills/unity-tests/scripts/unity_tests.py |
skills/unity-tests/references/EditModeTests.asmdef.json | .agents/skills/unity-tests/references/EditModeTests.asmdef.json |
skills/unity-tests/references/HealthTests.cs | .agents/skills/unity-tests/references/HealthTests.cs |
Already have an AGENTS.md or CLAUDE.md? The commands above overwrite it — download the file instead and merge the sections you want.
Files
Rules AGENTS.md Testable C# layout and the rules for running Unity tests. 21 lines
# AGENTS.md: Unity project with command-line tests
Unity 6 project. C# changes are checked by the Unity Test Framework, run headless. The `unity-tests` skill runs
the tests and reads the results; use it after every C# change.
## Code layout for testable C#
- Game logic in plain C# classes (no `MonoBehaviour`) in the runtime assembly, so Edit Mode tests can run it in
milliseconds. MonoBehaviours read input, call the logic and update the scene.
- Tests in `Assets/Tests/EditMode/` and `Assets/Tests/PlayMode/`, each with its own `.asmdef`. One test class per
class under test, named `<Class>Tests`.
- Never edit `Library/`, `Temp/`, `Logs/`, `obj/` or `UserSettings/`. Never delete or regenerate `.meta` files.
## Running tests
- The Editor binary is in `UNITY_PATH`, matching `ProjectSettings/ProjectVersion.txt`. Never run a different version.
- The project must be closed in the Editor for a command-line run. If it is open, ask the human.
- Unity exits 0 when no tests ran. A run is only green when at least one test ran and none failed.
## Done means
Edit Mode tests ran (and Play Mode tests, if you changed behaviour that needs frames), the summary shows 0 failed
and more than 0 total, no test was ignored or weakened, and you reported the command and the summary line. Adapter CLAUDE.md Imports AGENTS.md for Claude Code. 11 lines
# CLAUDE.md
@AGENTS.md
## Claude Code notes
- Skills from this loadout live in `.claude/skills/`: `unity-tests`. Use them when their description matches the task.
- Follow AGENTS.md above; where this file and AGENTS.md disagree, AGENTS.md wins.
<!-- From SetupBay "Unity tests from the command line, read properly" v1.0.0 — https://setupbay.com/loadouts/unity-test-runner/ --> Adapter GEMINI.md Imports AGENTS.md for Gemini CLI. 11 lines
# GEMINI.md
@./AGENTS.md
## Gemini CLI notes
- Skills from this loadout live in `.agents/skills/`: `unity-tests`. Use them when their description matches the task.
- Follow AGENTS.md above; where this file and AGENTS.md disagree, AGENTS.md wins.
<!-- From SetupBay "Unity tests from the command line, read properly" v1.0.0 — https://setupbay.com/loadouts/unity-test-runner/ --> Skill skills/unity-tests/SKILL.md Run tests headless and read the results. 51 lines
---
name: unity-tests
description: Run Unity Test Framework Edit Mode and Play Mode tests from the command line and read the NUnit results, including the zero-tests case Unity reports as success. Use after changing C# in a Unity project, when adding tests, or when the user asks whether the Unity tests pass.
---
# Unity tests from the command line
The Unity agent plugin can edit scripts and scenes; this skill is how you prove the C# still works. It runs the
Unity Test Framework headless and reads the result file, because the exit code alone is misleading:
| Exit | Meaning |
|---|---|
| 0 | every test passed **or no tests ran at all** (a filter that matches nothing, a missing test assembly) |
| 2 | one or more tests failed |
| 3 | run error: usually a compile error, so no tests ran |
| 4 | the test platform isn't installed |
## 1. Preconditions
- `ProjectSettings/ProjectVersion.txt` gives the Editor version. `UNITY_PATH` must point at that Editor's binary.
If it isn't set, ask the human for the path; do not guess another version (it would re-import the project).
- **The project must not be open in the Editor.** Batch mode refuses a project that is already open. If the human
has it open, ask them to close it, or to run the tests in Window → General → Test Runner and paste the result.
- `git status` clean, or the human knows you are about to run a re-import.
## 2. Edit Mode first
Edit Mode tests run plain C# without entering Play mode, in seconds. Put logic in plain classes so it can be tested
here, and keep MonoBehaviours thin.
- Test assembly: `Assets/Tests/EditMode/` with an `.asmdef` like `references/EditModeTests.asmdef.json`
(Editor-only, references `UnityEngine.TestRunner` and `UnityEditor.TestRunner`, `nunit.framework.dll`, and the
runtime assembly under test, constrained to `UNITY_INCLUDE_TESTS`). Save it with the `.asmdef` extension.
- Example test: `references/HealthTests.cs`. NUnit `[Test]` and `[TestCase]`; `Assert.That(x, Is.EqualTo(y))`.
- Play Mode tests (`[UnityTest]` coroutines, scenes, physics) go in `Assets/Tests/PlayMode/` with a separate
`.asmdef` that is not Editor-only. Use them for behaviour that needs frames.
## 3. Run
```bash
python3 .agents/skills/unity-tests/scripts/unity_tests.py run --platform EditMode
python3 .agents/skills/unity-tests/scripts/unity_tests.py run --platform EditMode --filter "Game.Tests.HealthTests"
python3 .agents/skills/unity-tests/scripts/unity_tests.py run --platform PlayMode
```
(Claude Code installs the skill under `.claude/skills/`.) It writes `TestResults/<platform>.xml` and `.log`
(add `TestResults/` to `.gitignore`), deletes old ones first so a stale file is never read, prints the Unity
command, each failing test with its message and first stack line, compile errors from the log, and skipped tests
with their reasons. Already have a results file? `unity_tests.py read TestResults/editmode.xml`.
## 4. Read it like a reviewer
- `NO TESTS RAN` is a failure, whatever Unity's exit code says. Fix the filter, the `.asmdef` or the platform.
- `COMPILE` lines: fix those first; nothing else ran.
- Never mark a test `[Ignore]`, delete it, or loosen an assertion to get green. If a test is wrong, say why and ask.
- Report the summary line (total, passed, failed, skipped) and the command you ran. Skill file skills/unity-tests/scripts/unity_tests.py Batch-mode runner and NUnit 3 results reader. 108 lines
#!/usr/bin/env python3
"""Run Unity Test Framework tests from the command line and read the NUnit results properly.
Usage:
python3 unity_tests.py run [--platform EditMode|PlayMode] [--filter REGEX] [--category NAME] [--project .]
python3 unity_tests.py read RESULTS.xml
`run` needs the Unity Editor binary in UNITY_PATH (for example
/Applications/Unity/Hub/Editor/6000.2.6f1/Unity.app/Contents/MacOS/Unity). The Editor must not have the project open.
It runs: Unity -batchmode -projectPath P -runTests -testPlatform X -testResults F -logFile L [-testFilter ...]
and leaves out -quit (the test run exits the Editor when it ends).
Why not trust the exit code alone: Unity exits 0 when every test passed and ALSO when no tests ran at all
(for example a -testFilter that matches nothing). 2 means tests failed, 3 a run error (often a compile error),
4 a platform that is not installed. This script fails on zero tests, lists each failure with its message,
and pulls compile errors out of the log.
Exit 0 only when at least one test ran and none failed. Standard library only.
"""
import os
import re
import subprocess
import sys
import xml.etree.ElementTree as ET
CODES = {0: "run completed", 2: "one or more tests failed", 3: "run error (compile error, crash or no test callbacks)", 4: "test platform not found"}
def read(path):
if not os.path.exists(path):
print(f"unity-tests: no results file at {path}; the run did not get as far as tests")
return 1
root = ET.parse(path).getroot()
run = root if root.tag == "test-run" else root.find(".//test-run")
if run is None:
print(f"unity-tests: {path} is not an NUnit 3 test-run file")
return 1
a = {k: run.get(k, "0") for k in ("total", "passed", "failed", "skipped", "inconclusive", "result", "duration")}
total, failed = int(a["total"]), int(a["failed"])
print(f"unity-tests: {a['total']} total, {a['passed']} passed, {a['failed']} failed, {a['skipped']} skipped, {a['inconclusive']} inconclusive ({a['result']})")
for case in run.iter("test-case"):
if case.get("result") == "Failed":
msg = (case.findtext("failure/message") or "").strip().splitlines()
where = (case.findtext("failure/stack-trace") or "").strip().splitlines()
print(f"FAILED {case.get('fullname')}: {msg[0] if msg else '(no message)'}")
if where:
print(f" at {where[0].strip()}")
for case in run.iter("test-case"):
if case.get("result") == "Skipped":
reason = (case.findtext("reason/message") or "").strip()
print(f"skipped {case.get('fullname')}{': ' + reason if reason else ''}")
if total == 0:
print("unity-tests: NO TESTS RAN. Unity still exits 0 here. Check -testFilter/-testCategory, the test assembly's .asmdef, and -testPlatform.")
return 1
return 1 if failed else 0
def compile_errors(log):
if not os.path.exists(log):
return []
text = open(log, encoding="utf-8", errors="replace").read()
errs = re.findall(r"^(Assets/[^\n(]+\(\d+,\d+\): error CS\d+: [^\n]+)", text, re.M)
if "another Unity instance is running" in text or "It looks like another Unity instance" in text:
errs.insert(0, "The project is open in another Unity Editor. Ask the human to close it, or run the tests in the Test Runner window.")
return list(dict.fromkeys(errs))
def run(argv):
unity = os.environ.get("UNITY_PATH")
if not unity:
print("unity-tests: set UNITY_PATH to the Unity Editor binary for this project's version (ProjectSettings/ProjectVersion.txt)")
return 2
opt = lambda n, d=None: argv[argv.index(n) + 1] if n in argv else d
project = os.path.abspath(opt("--project", "."))
platform = opt("--platform", "EditMode")
out = os.path.join(project, "TestResults")
os.makedirs(out, exist_ok=True)
results, log = os.path.join(out, f"{platform.lower()}.xml"), os.path.join(out, f"{platform.lower()}.log")
for p in (results, log):
if os.path.exists(p):
os.remove(p) # never read a stale file from an earlier run
cmd = [unity, "-batchmode", "-projectPath", project, "-runTests", "-testPlatform", platform, "-testResults", results, "-logFile", log]
if platform == "EditMode":
cmd.insert(2, "-nographics")
if opt("--filter"):
cmd += ["-testFilter", opt("--filter")]
if opt("--category"):
cmd += ["-testCategory", opt("--category")]
print("$ " + " ".join(cmd))
code = subprocess.run(cmd).returncode
print(f"unity exit {code}: {CODES.get(code, 'unknown')}")
for e in compile_errors(log):
print(f"COMPILE {e}")
status = read(results)
return status if code in (0, 2) else (code or 1)
def main(argv):
if argv[:1] == ["read"] and len(argv) == 2:
return read(argv[1])
if argv[:1] == ["run"]:
return run(argv[1:])
print(__doc__.strip(), file=sys.stderr)
return 2
if __name__ == "__main__":
sys.exit(main(sys.argv[1:])) Skill file skills/unity-tests/references/EditModeTests.asmdef.json Edit Mode test assembly definition to copy. 19 lines
{
"name": "Game.Tests.EditMode",
"rootNamespace": "Game.Tests",
"references": [
"Game.Runtime",
"UnityEngine.TestRunner",
"UnityEditor.TestRunner"
],
"includePlatforms": ["Editor"],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": true,
"precompiledReferences": ["nunit.framework.dll"],
"autoReferenced": false,
"defineConstraints": ["UNITY_INCLUDE_TESTS"],
"versionDefines": [],
"noEngineReferences": false
} Skill file skills/unity-tests/references/HealthTests.cs Example NUnit Edit Mode test. 30 lines
// Example Edit Mode test. Copy to Assets/Tests/EditMode/HealthTests.cs next to the test .asmdef.
// Tests plain C# logic (no scene, no frames), so it runs in milliseconds from the command line.
using NUnit.Framework;
namespace Game.Tests
{
public class HealthTests
{
[Test]
public void Damage_ReducesHealth_AndNeverGoesBelowZero()
{
var health = new Health(max: 10);
health.TakeDamage(4);
Assert.That(health.Current, Is.EqualTo(6));
health.TakeDamage(50);
Assert.That(health.Current, Is.EqualTo(0));
Assert.That(health.IsDead, Is.True);
}
[TestCase(0)]
[TestCase(-3)]
public void Damage_IgnoresZeroOrNegative(int amount)
{
var health = new Health(max: 10);
health.TakeDamage(amount);
Assert.That(health.Current, Is.EqualTo(10));
}
}
} All files: source zip · Licence MIT · By SetupBay · First listed
Credits
Public work that inspired this loadout. The wording here is our own; follow the links for the originals.
Installing and checks
How do I install Unity tests from the command line, read properly in Claude Code?
From your project root, put AGENTS.md, CLAUDE.md, skills/unity-tests/SKILL.md at .claude/skills/unity-tests/SKILL.md, skills/unity-tests/scripts/unity_tests.py at .claude/skills/unity-tests/scripts/unity_tests.py, skills/unity-tests/references/EditModeTests.asmdef.json at .claude/skills/unity-tests/references/EditModeTests.asmdef.json, skills/unity-tests/references/HealthTests.cs at .claude/skills/unity-tests/references/HealthTests.cs. The "Claude Code" tab on this page has the curl commands, or download https://setupbay.com/download/unity-test-runner/claude-code.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.
How do I install Unity tests from the command line, read properly in Codex CLI?
From your project root, put AGENTS.md, skills/unity-tests/SKILL.md at .agents/skills/unity-tests/SKILL.md, skills/unity-tests/scripts/unity_tests.py at .agents/skills/unity-tests/scripts/unity_tests.py, skills/unity-tests/references/EditModeTests.asmdef.json at .agents/skills/unity-tests/references/EditModeTests.asmdef.json, skills/unity-tests/references/HealthTests.cs at .agents/skills/unity-tests/references/HealthTests.cs. The "Codex CLI" tab on this page has the curl commands, or download https://setupbay.com/download/unity-test-runner/codex.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.
How do I install Unity tests from the command line, read properly in Cursor?
From your project root, put AGENTS.md, skills/unity-tests/SKILL.md at .agents/skills/unity-tests/SKILL.md, skills/unity-tests/scripts/unity_tests.py at .agents/skills/unity-tests/scripts/unity_tests.py, skills/unity-tests/references/EditModeTests.asmdef.json at .agents/skills/unity-tests/references/EditModeTests.asmdef.json, skills/unity-tests/references/HealthTests.cs at .agents/skills/unity-tests/references/HealthTests.cs. The "Cursor" tab on this page has the curl commands, or download https://setupbay.com/download/unity-test-runner/cursor.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.
How do I install Unity tests from the command line, read properly in Gemini CLI?
From your project root, put AGENTS.md, GEMINI.md, skills/unity-tests/SKILL.md at .agents/skills/unity-tests/SKILL.md, skills/unity-tests/scripts/unity_tests.py at .agents/skills/unity-tests/scripts/unity_tests.py, skills/unity-tests/references/EditModeTests.asmdef.json at .agents/skills/unity-tests/references/EditModeTests.asmdef.json, skills/unity-tests/references/HealthTests.cs at .agents/skills/unity-tests/references/HealthTests.cs. The "Gemini CLI" tab on this page has the curl commands, or download https://setupbay.com/download/unity-test-runner/gemini-cli.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.
How do I install Unity tests from the command line, read properly in Antigravity CLI?
From your project root, put AGENTS.md, skills/unity-tests/SKILL.md at .agents/skills/unity-tests/SKILL.md, skills/unity-tests/scripts/unity_tests.py at .agents/skills/unity-tests/scripts/unity_tests.py, skills/unity-tests/references/EditModeTests.asmdef.json at .agents/skills/unity-tests/references/EditModeTests.asmdef.json, skills/unity-tests/references/HealthTests.cs at .agents/skills/unity-tests/references/HealthTests.cs. The "Antigravity CLI" tab on this page has the curl commands, or download https://setupbay.com/download/unity-test-runner/antigravity-cli.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.
How do I install Unity tests from the command line, read properly in GitHub Copilot?
From your project root, put AGENTS.md, skills/unity-tests/SKILL.md at .agents/skills/unity-tests/SKILL.md, skills/unity-tests/scripts/unity_tests.py at .agents/skills/unity-tests/scripts/unity_tests.py, skills/unity-tests/references/EditModeTests.asmdef.json at .agents/skills/unity-tests/references/EditModeTests.asmdef.json, skills/unity-tests/references/HealthTests.cs at .agents/skills/unity-tests/references/HealthTests.cs. The "GitHub Copilot" tab on this page has the curl commands, or download https://setupbay.com/download/unity-test-runner/copilot.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.
What has been checked in Unity tests from the command line, read properly?
It passed the Level 1 automated install checks on 2026-10-24: the files parse, install to each agent's documented paths, and pass the safety scan. No AI agent has run it yet, so no agent pass or fail is claimed.
More for Claude Code, Codex, Cursor, Gemini CLI, Antigravity CLI and GitHub Copilot.