Skip to content
Automation
Skill

/gdunit-driver

Run gdUnit4 unit tests and parse results into structured output. Use this skill after writing or modifying code to verify correctness via unit tests, when diagnosing test failures, or when writing new test files. Triggers: "run tests", "test fails", "write a test", any

From plugin
godotmaker
55941 skills7 agents15 hooks

Claude Code

$ npx -y skills add RandallLiuXin/GodotMaker --skill gdunit-driver --agent claude-code

SKILL.md

gdunit-driver.SKILL.md
name: gdunit-driver
description: |
  Run gdUnit4 unit tests and parse results into structured output.
  Use this skill after writing or modifying code to verify correctness via unit tests,
  when diagnosing test failures, or when writing new test files.
  Triggers: "run tests", "test fails", "write a test", any gdUnit4/unit test mention.
  Supports both GDScript (.gd) and C# (.cs) test files.

gdUnit4 Test Driver

$ARGUMENTS

1. Locate the Godot executable

Read the path from the project's config file. This avoids hardcoding paths that differ per machine.

# From the project root:
python tools/agent_runtime.py godot_path

2. Run tests

The CLI runner across all supported versions (v4.x, v5.x, v6.x) is `addons/gdUnit4/bin/GdUnitCmdTool.gd`. The path uses capital-U `gdUnit4/` to match the upstream repo layout — Windows is case-insensitive but Godot's global script registry de-duplicates by exact path string, so a casing mismatch between the runner invocation and the on-disk directory triggers `Class "..." hides a global script class` parse errors and a non-zero exit.

# Single file
"<godot_path>" --headless -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd \
  --add res://test/test_example.gd --ignoreHeadlessMode

# Multiple files
"<godot_path>" --headless -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd \
  --add res://test/test_physics.gd --add res://test/test_spawner.gd \
  --ignoreHeadlessMode

# All tests in a directory
"<godot_path>" --headless -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd \
  --add res://test/ --ignoreHeadlessMode

Notes:

  • Include `--ignoreHeadlessMode` for headless runs.
  • Use `--add` to enqueue test files or directories (repeat the flag for multiples).
  • Runner path needs the `res://` prefix and the capital-U `addons/gdUnit4/` casing.
  • No `::method` syntax for single test methods — run the whole file instead.

C# tests

`GdUnitCmdTool.gd` supports C# test files too, but ensure `dotnet build` passes first — gdUnit4 runs compiled assemblies, not source files.

dotnet build && "<godot_path>" --headless -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd \
  --add res://test/csharp/TestExample.cs --ignoreHeadlessMode

Useful flags

| Flag | Purpose | |------|---------| | `--add <path>` | Add test path to execution (file or directory; repeat to enqueue multiple) | | `--ignoreHeadlessMode` | Allow headless execution | | `--report-directory <path>` | Override report output directory |

Timeout

gdUnit4 has a default test timeout (configurable in `GdUnitSettings`). If tests hang:

  • Check for infinite loops or unresolved `await` calls
  • Tests involving scene tree operations need explicit timeouts on await calls
  • Kill the process after 120 seconds if no output appears

3. Parse results

Stdout parsing

`GdUnitCmdTool.gd` output contains ANSI color codes — strip them before parsing. Format:

Run Test Suite res://test/test_example.gd
  Run Test: res://test/test_example.gd > test_basic_math :PASSED 38ms
  Run Test: res://test/test_example.gd > test_will_fail :FAILED 39ms
  Report:
    line <n/a>: Expecting:
     '2'
     but was
     '1'

Statistics: | 2 tests cases | 0 error | 1 failed | 0 flaky | 0 skipped | 0 orphans |
Executed test suites: (1/1)
Executed test cases: (2/2)
Total time:        128ms
Exit code: 100

Notes:

  • Per-test lines start with `Run Test:`; suite lines with `Run Test Suite`.
  • Duration is reported in milliseconds (`38ms`).
  • Failure line numbers may show `line <n/a>` instead of exact lines.
  • Summary uses `Statistics:` with pipe-delimited counts.
  • Exit code 100 = test failures (not 1).

Extract from each test line:

  • **Name**: the `test_*` function name (after `>`).
  • **Status**: `PASSED`, `FAILED`, `SKIPPED`, `ERROR`.
  • **Duration**: `Nms` after the status.
  • **Failure message**: indented `Report:` lines following a FAILED test (assertion details + source location if available).

JUnit XML report

Use `--report-directory <path>` for JUnit XML reports. The default report directory is `res://reports/`, which maps to project-root `reports/`.

<testsuites>
  <testsuite name="TestExample" tests="4" failures="1" errors="0" skipped="1">
    <testcase name="test_basic_math" classname="TestExample" time="0.002"/>
    <testcase name="test_will_fail" classname="TestExample" time="0.003">
      <failure message="Expecting '2' but was '1'" type="AssertionError">
        at: res://test/test_example.gd:15
      </failure>
    </testcase>
  </testsuite>
</testsuites>

Structured output format

Report results in this format:

## Test Results: test_example.gd

| Test | Status | Duration |
|------|--------|----------|
| test_basic_math | PASS | 0.002s |
| test_string_concat | PASS | 0.001s |
| test_will_fail | FAIL | 0.003s |
| test_skipped | SKIP | 0.000s |

**Summary: 4 total, 2 passed, 1 failed, 1 skipped, 0 errors**

### Failures

**test_will_fail** (res://test/test_example.gd:15)
> Expecting '2' but was '1'

Always include the file:line for failures — the agent (or user) needs this to navigate to the problem.

4. Writing tests

When the agent needs to write a new test file, follow these patterns.

GDScript test structure

# res://test/test_my_system.gd
extends GdUnitTestSuite

# Runs before each test
func before_test() -> void:
    pass

# Runs after each test
func after_test() -> void:
    pass

func test_example() -> void:
    assert_int(2 + 2).is_equal(4)

func test_string_operations() -> void:
    assert_str("hello").contains("ell")

Key assertion API

# Integers
assert_int(value).is_equal(expected)
assert_int(value).is_greater(threshold)
assert_int(value).is_between(low, high)

# Floats
assert_float(value).is_equal_approx(expected, 0.001)

# Strings
assert_str(value).is_equal(expected)
assert_str(value).contains(substring)
assert_str(value).starts_with(prefix)

# Booleans
assert_bool(value).is_true()
assert_bool(value).is_false()

#
Read more
@randallliuxin
Ships withgodotmaker

Autonomous text-to-game pipeline for Godot, powered by Claude Code,Codex,Opencode

55941 skills7 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
559
Star history of RandallLiuXin/GodotMaker on GitHub, a chart by star-history.com

Other skills on godotmaker.

platform-strip

platform-strip

Generate non-pixel-art, horizontally repeatable platform strips from real image sources as fixed Texture2D cells or AtlasTexture…

More skills from other plugins.

agent-builder

agent-builder

Load immediately after an Agent intent, before the first agent_builder_* call. Governs how you create, configure, test, and…

n8n12d209k
@n8n-io@n8n-ioInstall Skill
browser-use

browser-use

Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…

@browser-use@browser-useInstall Skill
agent-browser

agent-browser

Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…

@vercel-labs-2@vercel-labs-2Install Skill
add-anydoc

add-anydoc

Add local office-document-to-Markdown conversion to NanoClaw agent containers with the pinned Firecrawl AnyDoc CLI. Use when…

@nanocoai@nanocoaiInstall Skill

Questions about gdunit-driver.

Which coding agents can use gdunit-driver?
gdunit-driver installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.