跳到正文
cccskills
免费在 GitHub 公开

godot-testing

Use when writing tests for Godot projects — TDD workflow with GUT and gdUnit4, covers both GDScript and C#

中文简介正在准备中。当前显示原文说明。

查看安装方法

包含的文件(6)

  • SKILL.md9.7 KB
  • gdunit4-reference.md10.5 KB
  • gut-reference.md8.6 KB
  • references/running-tests.md3.2 KB
  • references/tdd-workflow.md5.9 KB
  • references/testing-patterns.md5.0 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Godot Testing

This skill covers test-driven development (TDD) for Godot 4.3+ projects using GUT (Godot Unit Testing) and gdUnit4. It includes framework selection, full RED-GREEN-REFACTOR examples, test structure, running tests in CI, and common testing patterns.

Related skills: godot-code-review for review checklists, dependency-injection for test-friendly architecture, export-pipeline for CI/CD test automation.

Framework Selection

FeatureGUTgdUnit4
LanguageGDScript-first, limited C#GDScript + C# (first-class)
InstallAssetLib or git submoduleAssetLib or git submodule
Editor integrationBuilt-in GUT panelBuilt-in inspector + panel
Mockingdouble() / stub() APImock() / spy() API
Scene testingadd_child_autofree()auto_free() + scene runner
CI supportgut_cmdln.gd CLI scriptruntest.sh / GdUnitCmdTool.gd
C# supportMinimal (GDScript wrappers only)Native C# assertions + lifecycle
MaturityEstablished (Godot 3 + 4)Godot 4 focused, actively updated
Best forPure GDScript projectsMixed GDScript/C# or C#-only

Rule of thumb: Use GUT for GDScript-only projects. Use gdUnit4 for C# projects or when you need first-class C# support and scene runner utilities.


TDD Workflow: RED-GREEN-REFACTOR

The standard Test-Driven Development cycle: write a failing test (RED), write minimal code to pass (GREEN), then refactor without breaking the test. Each step has its own discipline — don't skip RED (you'll write tests that pass trivially), and don't skip REFACTOR (technical debt compounds).

See references/tdd-workflow.md for a worked GDScript + C# example walking through all three steps on a HealthComponent.


Test Directory Structure

res://
├── .gutconfig.json                       # GUT default config file (optional)
├── src/
│   └── components/
│       ├── health_component.gd
│       └── HealthComponent.cs
└── tests/
    ├── unit/
    │   ├── test_health_component.gd      # GUT: test_ prefix (default -gprefix)
    │   └── HealthComponentTest.cs        # gdUnit4 C#: [TestSuite] attribute
    └── integration/
        ├── test_player_scene.gd
        └── PlayerSceneTest.cs

Naming conventions

FrameworkGDScript fileC# fileTest method prefix/attribute
GUTtest_*.gdN/Afunc test_*()
gdUnit4any name (*_test.gd when generated)*Test.csfunc test_*() / [TestCase]

Running Tests

Both frameworks ship a CLI runner. GUT: addons/gut/gut_cmdln.gd invoked via godot --headless --path . -s addons/gut/gut_cmdln.gd -gexit (without -gexit the run never quits). gdUnit4: addons/gdUnit4/runtest.sh -a res://tests (wraps bin/GdUnitCmdTool.gd; under --headless it also needs --ignoreHeadlessMode), or the editor's GdUnit dock. CI: tag-triggered or PR-triggered GitHub Action that installs Godot, runs the suite, exits non-zero on failure.

See references/running-tests.md for full GUT and gdUnit4 CLI invocations + a copy-pasteable GitHub Actions workflow.


Testing Patterns

Four common patterns: scenes with nodes (instantiate via add_child in before_each, free in after_each), signal testing (assert that emitting works and connect-then-emit fires), mocking/doubling (gdUnit4 mock() in GDScript; in C#, hand-rolled fakes via @export injection), async (await yields, signals, frames in tests).

See references/testing-patterns.md for full code on each pattern (GDScript + C# where applicable).


Common Assertions

GUT assertions

AssertionDescription
assert_eq(actual, expected)Equality
assert_ne(actual, expected)Not equal
assert_true(value)Is truthy
assert_false(value)Is falsy
assert_null(value)Is null
assert_not_null(value)Is not null
assert_gt(actual, expected)Greater than
assert_lt(actual, expected)Less than
assert_gte(actual, expected)Greater than or equal
assert_lte(actual, expected)Less than or equal
assert_has(collection, item)Collection contains item
assert_does_not_have(collection, item)Collection does not contain item
assert_string_contains(str, sub)String contains substring
assert_almost_eq(actual, expected, margin)Float equality within margin
assert_signal_emitted(obj, signal_name)Signal was emitted
assert_signal_not_emitted(obj, signal_name)Signal was not emitted

gdUnit4 assertions (GDScript + C#)

GDScriptC#Description
assert_that(val).is_equal(exp)AssertThat(val).IsEqual(exp)Equality
assert_that(val).is_not_equal(exp)AssertThat(val).IsNotEqual(exp)Not equal
assert_that(val).is_true()AssertThat(val).IsTrue()Is true
assert_that(val).is_false()AssertThat(val).IsFalse()Is false
assert_that(val).is_null()AssertThat(val).IsNull()Is null
assert_that(val).is_not_null()AssertThat(val).IsNotNull()Is not null
assert_that(val).is_greater(exp)AssertThat(val).IsGreater(exp)Greater than
assert_that(val).is_less(exp)AssertThat(val).IsLess(exp)Less than
assert_that(val).is_between(min, max)AssertThat(val).IsBetween(min, max)In range (inclusive)
assert_that(arr).contains([a, b])AssertThat(arr).Contains(a, b)Array contains elements
assert_that(str).contains("sub")AssertThat(str).Contains("sub")String contains substring
assert_that(val).is_equal_approx(exp, margin)AssertThat(val).IsEqualApprox(exp, margin)Float within margin
await assert_signal(mon).is_emitted("name")await AssertSignal(node).IsEmitted("name")Signal emitted

What NOT to Test

Avoid testing things that add noise without catching real bugs:

  • Godot engine internals — do not assert that Node.add_child() works or that @export variables show up in the editor
  • Private implementation details — test behavior through the public API; if a refactor breaks a test that covers only private state, the test is wrong
  • Visual/rendering output — pixel-level rendering results are brittle; test the data driving the visuals instead
  • Timing-sensitive floats without margins — use assert_almost_eq / IsEqualApprox for physics values
  • One-liners that wrap a built-in — a property getter that just returns a field needs no test
  • Every possible invalid input — test the documented contract, not every imaginable misuse

Checklist

  • Each test file matches the naming convention for the chosen framework (GUT test_*.gd; gdUnit4 *_test.gd / *Test.cs)
  • Tests extend the correct base class (GutTest / GdUnitTestSuite); C# gdUnit4 suites are plain [TestSuite] classes
  • C#: gdUnit4.api pinned to 4.3.x on Godot 4.3; on 5.x (Godot 4.4+), suites that touch nodes or scenes carry [RequireGodotRuntime]
  • Nodes added to the scene tree use add_child_autofree or auto_free — never manual queue_free()
  • Signals are watched before the action that triggers them
  • Mocks/doubles are used for external dependencies, not for the unit under test
  • Each test covers exactly one behavior (one logical assertion per test)
  • CI workflow runs tests headlessly on every push and PR
  • Flaky async tests use explicit timeouts, not arbitrary sleep durations
  • Tests pass before merging (RED is only acceptable while actively implementing)

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D, custom drawing, and 2D meshes in Godot 4.3+

中文简介正在准备中。当前显示原文说明。

jame581/GodotPrompter8622026年10月22日 更新

Use when working with 3D-specific systems — materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion culling, and decals in Godot 4.3+

中文简介正在准备中。当前显示原文说明。

jame581/GodotPrompter8622026年10月22日 更新

Use when building character abilities — Resource-based abilities with cost/cooldown/cast, buffs/debuffs, stat modifiers, gameplay tags, and HUD binding

中文简介正在准备中。当前显示原文说明。

jame581/GodotPrompter8622026年10月22日 更新

Use when creating Godot editor plugins — EditorPlugin, @tool scripts, custom inspectors, and dock panels

中文简介正在准备中。当前显示原文说明。

jame581/GodotPrompter8622026年10月22日 更新

Use when implementing AI movement — NavigationAgent2D/3D, steering behaviors, behavior trees, and patrol patterns

中文简介正在准备中。当前显示原文说明。

jame581/GodotPrompter8622026年10月22日 更新

Use when implementing animations — AnimationPlayer, AnimationTree, blend trees, state machines, sprite animation, and code-driven animation

中文简介正在准备中。当前显示原文说明。

jame581/GodotPrompter8622026年10月22日 更新

查看 jame581 的全部技能

报告此技能的问题