gdUnit4
llms.txt1.3k starsChanged 25 days agoMITView on GitHub
A Godot 4 embedded unit testing framework (plugin) supporting GDScript and C#. GdUnit4 v7.0.0 — supports Godot 4.7–4.8. C# targets net9.0 (.NET SDK 9.0.308). The framework is self-tested: it uses itself to run its own test suite. The plugin lives entirely under addons/gdUnit4/. License: MIT Keywords: Godot unit testing, GDScript testing framework, Godot 4 plugin, game testing, test-driven development, TDD, Godot C# testing, automated testing, unit test, integration test, scene testing, signal testing, mock, spy, stub, fuzzing, parameterized tests, CI/CD,…
Files
# GdUnit4
> A Godot 4 embedded unit testing framework (plugin) supporting GDScript and C#.
GdUnit4 v7.0.0 — supports Godot 4.7–4.8. C# targets net9.0 (.NET SDK 9.0.308). The framework is self-tested: it uses itself to run its own test suite. The plugin lives entirely under `addons/gdUnit4/`.
**License:** MIT
Keywords: Godot unit testing, GDScript testing framework, Godot 4 plugin, game testing, test-driven development, TDD, Godot C# testing, automated testing, unit test, integration test, scene testing, signal testing, mock, spy, stub, fuzzing, parameterized tests, CI/CD, GitHub Actions, JUnit XML, HTML report
## Why GdUnit4
GdUnit4 is a feature-rich testing framework for Godot 4, designed to make writing and running tests enjoyable for both GDScript and C# developers.
- **Dual-language support** — GDScript and C# in a single framework
- **Fluent assertion API** — chainable, type-aware assertions with descriptive failure messages
- **Full mock/stub/spy support** — isolate dependencies and verify interactions
- **Scene Runner** — simulate user input (keyboard, mouse, actions) on live nodes/UI in tests
- **Signal assertions** — await and assert signal emissions with timeout support
- **Fuzzing / parameterized tests** — data-driven test cases with built-in fuzzers
- **CI/CD ready** — JUnit XML and HTML reports, headless mode, GitHub Actions integration
- **Godot editor integration** — Test Inspector panel with run/re-run, green/red tree, filtering
- **Test hooks** — `before`/`after` (suite-level) and `before_test`/`after_test` (per-test) setup and teardown callbacks
- **Session hooks** — global setup and teardown logic that runs once per test session via `GdUnitTestSessionHook`
- **Integrated update tool** — check for and install new releases directly from the Godot editor
- **Asset Library** — installable directly from the Godot Editor Asset Library
## Installation
**Via Godot Asset Library** (recommended): Search for "GdUnit4" in the Godot Editor → AssetLib tab.
**Via release download**: Download the latest `.zip` from [GitHub releases](https://github.com/MikeSchulze/gdUnit4/releases), extract into your project's `addons/` folder, then enable the plugin in *Project → Project Settings → Plugins*.
## Quick Start (GDScript)
```gdscript
extends GdUnitTestSuite
func test_string_contains() -> void:
assert_str("Hello GdUnit4").contains("GdUnit4")
func test_array_has_size() -> void:
assert_array([1, 2, 3]).has_size(3).contains(1, 2)
func test_signal_emitted() -> void:
var timer := auto_free(Timer.new())
add_child(timer)
timer.start(0.1)
await assert_signal(timer).is_emitted("timeout")
func test_mock_example() -> void:
var mock_node := mock(Node)
mock_node.get_name()
verify(mock_node).get_name()
func test_scene_runner() -> void:
# load a scene and wrap it in a runner
var runner := scene_runner("res://scenes/MyGame.tscn")
# simulate a key press and advance frames
runner.simulate_key_pressed(KEY_SPACE)
await runner.simulate_frames(30)
# assert expected scene state
assert_object(runner.find_child("Player")).is_not_null()
```
## Quick Start (C#)
```csharp
using GdUnit4;
using static GdUnit4.Assertions;
[TestSuite]
public class MyTest
{
[TestCase]
public void StringContains()
=> AssertThat("Hello GdUnit4").Contains("GdUnit4");
[TestCase]
public void ArrayHasSize()
=> AssertThat(new[] { 1, 2, 3 }).HasSize(3);
// Parameterized test — each [TestCase] attribute is one run
[TestCase("foo", 3)]
[TestCase("hello", 5)]
public void StringLength(string value, int expectedLength)
=> AssertThat(value).HasLength(expectedLength);
}
```
For C# signal assertions, mocking, and scene runner see the [documentation site](https://godot-gdunit-labs.github.io/gdUnit4/latest/).
## Organisation
GdUnit4 is part of the **[godot-gdunit-labs](https://github.com/godot-gdunit-labs)** GitHub organisation, which bundles all related projects:
- **[GdUnit4](https://github.com/godot-gdunit-labs/gdUnit4)** — the core Godot plugin (GDScript + C# via GDNative bindings)
- **[GdUnit4Net](https://github.com/godot-gdunit-labs/gdUnit4Net)** — standalone .NET / C# test adapter and NuGet package
- **[gdUnit4NetExamples](https://github.com/godot-gdunit-labs/gdUnit4NetExamples)** — example projects showing C# test setup and patterns
- **[gdUnit4-action](https://github.com/godot-gdunit-labs/gdUnit4-action)** — GitHub Action for running GdUnit4 tests in CI pipelines
## Docs
- [Documentation site](https://godot-gdunit-labs.github.io/gdUnit4/latest/): Full reference — assertions, mocking, spying, scene runner, fuzzing, CI setup
- [GitHub organisation](https://github.com/godot-gdunit-labs): All related repositories
- [CONTRIBUTING.md](https://github.com/MikeSchulze/gdUnit4/blob/master/CONTRIBUTING.md): Contribution guidelines
- [Discord server](https://discord.gg/rdq36JwuaJ): Community support and general discussion
- [Patreon](https://www.patreon.com/cw/GodotGdUnitLabs): Support the project
## Running Tests (CLI)
```bash
# Set Godot binary, then run all tests
export GODOT_BIN=/path/to/godot
./addons/gdUnit4/runtest.sh
# Run a specific path
./addons/gdUnit4/runtest.sh --godot_binary /path/to/godot -a res://addons/gdUnit4/test/asserts/
```
## Plugin Structure
```
addons/gdUnit4/
├── plugin.cfg # Plugin metadata and version
├── plugin.gd # EditorPlugin entry point
├── bin/ # CLI tools (GdUnitCmdTool.gd, GdUnitCopyLog.gd)
├── src/ # All framework source code
└── test/ # Self-tests (mirrors src/ structure)
```
For full source module breakdown, coding conventions, and contributor guidelines see [llms-full.txt](llms-full.txt).
Trending
Quiet since July.about the whole repository
Who's talking about MikeSchulze/gdUnit4
- @gareththegeek.bsky.social“When things get serious you gotta break out the unit tests even in #gamedev ! Thanks gdUnit4 for having my …”Bluesky · Oct 27, 2025 · 21 likes
- MikeSchulze/gdUnit3“GD-47: Add test examples to show howto write good/bad tests”GitHub · Apr 5, 2021 · 10 reactions
- godotengine/godot“GDScript 2.0: Memory leaks on static methods”GitHub · Dec 27, 2023 · 4 reactions
- godot-gdunit-labs/gdUnit4“GD-912: GDUnit4 fails to delete directories containing hidden files”GitHub · Sep 28, 2025 · 2 reactions
- godot-gdunit-labs/gdUnit4“GD-204: CONTRIBUTE.md misses the wished workflow AND has wrong link”GitHub · Jun 13, 2023 · 2 reactions
The biggest 5 of 52 mentions linking to the repository that our crawl found. Each line is their own headline.
See all 52
Talked about on GitHub and Bluesky (52 times).
On GitHub · 50
- Apr 5, 2021GD-47: Add test examples to show howto write good/bad tests — MikeSchulze/gdUnit310 reactions
- Dec 27, 2023GDScript 2.0: Memory leaks on static methods — godotengine/godot4 reactions · 5 comments
- Sep 28, 2025GD-912: GDUnit4 fails to delete directories containing hidden files — godot-gdunit-labs/gdUnit42 reactions · 1 comment
- Jun 13, 2023GD-204: CONTRIBUTE.md misses the wished workflow AND has wrong link — godot-gdunit-labs/gdUnit42 reactions
- Aug 16, 2025[DOC-856] Update `await_input_processed` examples — godot-gdunit-labs/gdUnit41 reaction
45 more on GitHub
- Aug 11, 2025[DOC-842] Usage of `append_error_message` and `override_error_message` — godot-gdunit-labs/gdUnit41 reaction · 1 comment
- Apr 23, 2024GD-409: Fix do skip excluded test suites by runner configuration — godot-gdunit-labs/gdUnit41 reaction
- Jul 12, 2023Godot 4.1 crashes on simple plugin print statement — godotengine/godot1 reaction · 5 comments
- Jul 10, 2023Godot 4.1 crash at exit with `corrupted size vs. prev_size while consolidating` — godotengine/godot1 reaction · 5 comments
- Jan 26, 2023GD-88: Run test without debug does not detect script errors and ends with success — godot-gdunit-labs/gdUnit41 reaction
- Jul 19, 2026Repeatable GdUnit4 dogfood harness ([ticket]) — kphutt/gdmutant0 reactions
- Nov 1, 2025Helper methods of Fuzzers returns strongly typed variants of Fuzzer — godot-gdunit-labs/gdUnit40 reactions · 1 comment
- Oct 29, 2025GD-969: Decoupling editor interface calls from test execution — godot-gdunit-labs/gdUnit40 reactions · 2 comments
- Oct 28, 2025GD-969: Allow running tests in exported projects and on devices — godot-gdunit-labs/gdUnit40 reactions · 6 comments
- Oct 25, 2025GD-961: Using CmdTool in CI fails with 101 when orphans detected — godot-gdunit-labs/gdUnit40 reactions · 6 comments
- Sep 21, 2025DOC-857: Update the fuzzers doc page — godot-gdunit-labs/gdUnit40 reactions
- Aug 18, 2025Docs: Guide for reliable headless & command-line execution — godot-gdunit-labs/gdUnit40 reactions · 3 comments
- Aug 7, 2025Filesystem scan spams `update_scripts_classes` messages — godotengine/godot0 reactions · 9 comments
- Jun 5, 2025GD-739: Invalid call. Nonexistent function 'push_back' in base 'Nil' when running >200 tests, error does not occur when running tests individually — godot-gdunit-labs/gdUnit40 reactions · 11 comments
- Apr 5, 2025GD-635: Fix test case counting. — godot-gdunit-labs/gdUnit40 reactions
- Apr 5, 2025GD-682: Rework on GdUnit4Net API Godot bridge — godot-gdunit-labs/gdUnit4Net0 reactions
- Mar 28, 2025GD-721: `[Master]` "Could not find type "GdUnitTestCIRunner" in the current scope." — godot-gdunit-labs/gdUnit40 reactions
- Mar 9, 2025GD-704: Input action dead zone is being passed as input strength when simulating actions — godot-gdunit-labs/gdUnit40 reactions · 1 comment
- Mar 9, 2025GD-703: Cannot run tests in Godot C# edition when project only uses GDScript — godot-gdunit-labs/gdUnit40 reactions · 5 comments
- Mar 8, 2025Godo4.4-stable: Crash on Ubuntu 22.04.5 at exit with signal 11 — godotengine/godot0 reactions · 3 comments
- Mar 2, 2025GD-693: Add how to export Games with installed gdunit4 plugin to FAQ — godot-gdunit-labs/gdUnit40 reactions
- Mar 1, 2025GD-635: Reimplement tree vs flat view — godot-gdunit-labs/gdUnit40 reactions
- Feb 26, 2025GD-653: Simplify GdUnitEvent by using the GdUnitGUID — godot-gdunit-labs/gdUnit40 reactions
- Feb 25, 2025GD-635: Store the test case record on tree item and used as execute argument instead of `resource_path` — godot-gdunit-labs/gdUnit40 reactions
- Feb 22, 2025GD-635: Rework on test discovery guard — godot-gdunit-labs/gdUnit40 reactions
- Feb 19, 2025GD-635: Comand line tool returns 0 on failed tests — godot-gdunit-labs/gdUnit40 reactions
- Feb 6, 2025GD-635: Merge cmd tool runner and default runner to reduce code dupli… — godot-gdunit-labs/gdUnit40 reactions
- Feb 5, 2025GD-635: Fix test run statistics counters — godot-gdunit-labs/gdUnit40 reactions
- Feb 4, 2025GD-635: Update progress bar counters — godot-gdunit-labs/gdUnit40 reactions
- Feb 3, 2025GD-635: [Test Explorer]: Implement test discovery to build the test tree — godot-gdunit-labs/gdUnit40 reactions
- Jan 28, 2025GD-653: Using the discovery sink to count discovered test on progressbar — godot-gdunit-labs/gdUnit40 reactions
- Jan 27, 2025GD-645: Spying on a scene with `@onready` properties loses the property values — godot-gdunit-labs/gdUnit40 reactions
- Jan 24, 2025GD-635: Add test case discovery sink — godot-gdunit-labs/gdUnit40 reactions
- Jan 24, 2025GD-635: Introduce new test case record — godot-gdunit-labs/gdUnit40 reactions
- Jan 2, 2025GD-624: Add `is_inheriting` and `is_not_inheriting` to object assert — godot-gdunit-labs/gdUnit40 reactions
- Dec 29, 2024GD-616: Added shortcuts for context menus, were removed by mistake — godot-gdunit-labs/gdUnit40 reactions
- Dec 28, 2024GD-616: fix file type check on filesystem context menu checks — godot-gdunit-labs/gdUnit40 reactions
- Dec 28, 2024GD-616: Use `EditorContextMenuPlugin` for Godot4.4.x — godot-gdunit-labs/gdUnit40 reactions
- Dec 3, 2024GD-168: Incorrect assertion messages — godot-gdunit-labs/gdUnit4Net0 reactions · 15 comments
- Nov 7, 2024GD-594: Fix mock fails on class with parameter getter setter — godot-gdunit-labs/gdUnit40 reactions
- Nov 4, 2024GD-592: Fixed the detection of parameterized test data changes in `TestDiscoveryGuard` to notify the test explorer and update the structure. — godot-gdunit-labs/gdUnit40 reactions
- Sep 19, 2024GD-573: Fixed the inspector double-click, inherited tests to jump to the script where the test are located — godot-gdunit-labs/gdUnit40 reactions
- Sep 18, 2024GD-563: Fix, parameterized test not executed when using typed arrays end ends with invalid success state — godot-gdunit-labs/gdUnit40 reactions
- Sep 9, 2024GD-566: Update HTML report page look & feel — godot-gdunit-labs/gdUnit40 reactions
- Jul 30, 2024Add Unit Tests with GDUnit4 — dragonforge-dev/spiritual_timekeeper0 reactions
On Bluesky · 2
- Oct 27, 2025When things get serious you gotta break out the unit tests even in #gamedev ! Thanks gdUnit4 for having my back writing C# unit tests for… — @gareththegeek.bsky.social21 likes and reposts
- Jun 25, 2025Ok I'm in love github.com/MikeSchulze/... — @maxouwell.bsky.social0 likes and reposts · 1 reply
Other versions1 project uses a version of this.
Word for word · 1
- godot-gdunit-labs/gdUnit4★ 1.3k100% same
Edited · 0
None found.
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository3 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- llms-full.txtllms.txt
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

