メインコンテンツまでスキップ

Tools for test-writer

Running automated tests to confirm red/green​

Test command:

mise exec -- godot --headless -s addons/gut/gut_cmdln.gd -gdir=res://tests/unit -gexit

Uses GUT v9.7.1, installed via gd-plug (declared in plug.gd, addons/gut is gitignored like the project's other addons). Options also live in .gutconfig.json at the repo root. Exit code is 0 on all-pass, 1 on any failure — safe for a Red→Green loop.

On a fresh clone, or after plug.gd install/update touches addons/, run godot --headless --import once first — otherwise GUT's class_names aren't resolved yet and the run errors out.

A bare godot works only where mise's shims are on PATH; mise exec -- resolves it from mise.toml either way.

GUT will not tell you a test passed for the wrong reason​

This is the failure mode that has actually cost this project time, repeatedly. A test passes when its assertions hold — not when they were meaningful:

  • An assertion that iterates a collection is vacuously true when the collection is empty.
  • A comparison between two outcomes holds trivially when both sides are untouched, because the thing under test never ran.
  • An assertion that "nothing happened" is satisfied by any reason nothing happened, including an unrelated gate rejecting the operation first.
  • Arithmetic that lands on a whole number cannot distinguish "rounded correctly" from "never rounded at all".

So: after a red→green transition, check what actually ran, not just the totals line. Pick fixture values where the right answer, the wrong answer, and the not-implemented answer are three different numbers, and assert against the wrong ones too (assert_ne). When a test asserts a rejection, make sure the mechanism under test is the only thing that could produce it.

Verifying editor/game behaviour that a headless test can't reach​

Consider godot-ai before writing a manual-test document for something it can actually drive (scene state, node properties, screenshots) — if it can, a manual step may be the wrong call. That file has the criterion for when it applies.

Linting the tests you write​

gdlint has no hook behind it, so run it before you finish — see docs/tools/gdtoolkit.md:

mise exec -- gdlint tests/

Where new test files belong​

res://tests/ (top-level, non-recursive) is reserved for the Godot AI addon's own McpTestSuite-based test_manage/test_run MCP tools — those only work with a live editor + MCP connection, not headless/CI. Write new GUT tests one level down, in res://tests/unit/, so the two test systems don't collide.