Releases: godot-gdunit-labs/gdUnit4Net
v5.0.0
🚀 GdUnit4 v5.0.0 - Major Architecture Overhaul
Breaking Changes ⚠️
Test Engine Redesign: GdUnit4 v5.0.0 introduces a completely reworked test engine that no longer requires the Godot runtime by default. This significantly improves test performance and enables testing in CI/CD environments without Godot installations.
Migration Required: Existing tests that depend on Godot runtime features (scenes, nodes, resources, etc.) must now be explicitly marked with the [RequireGodotRuntime] attribute.
New Features ✨
🎯 Selective Godot Runtime
[RequireGodotRuntime]: Annotate classes or methods that need Godot runtime context- Tests without this attribute run in fast, lightweight mode
- Dramatically improves test execution speed for logic-only tests
📊 Enhanced Debugging & Output
<CaptureStdOut>true</CaptureStdOut>: Capture console output and Godot prints in test results[GodotExceptionMonitor]: Monitor and report exceptions from Godot's main thread:- Catches exceptions in node callbacks (
_Ready,_Process, etc.) - Monitors scene tree operations
- Reports "silent" Godot exceptions as test failures
- Catches exceptions in node callbacks (
[ThrowsException]: Comprehensive exception testing with precise validation- Better error reporting and diagnostics
🔧 Advanced Test Configuration
[DataPoint(nameof(DataSource))]: Create data-driven tests with support for:- Static properties and methods as data sources
- Parameterized data methods with arguments
- Async data sources with
IAsyncEnumerable<object[]> - External class data sources
[ThrowsException(typeof(ArgumentException), "message")]: Verify expected exceptions with:- Exception type validation
- Message matching
- Source file and line number verification
- Support for multiple expected exception types
- Full VSTest filter support: Use standard test filtering in Visual Studio and
dotnet test [TestCategory("CategoryA")]: Organize tests with categories[Trait("Category", "A")]: Add custom traits for test organization
Migration Guide 📋
Before v5.0.0:
[Test]
public void MyTest()
{
// All tests ran in Godot runtime
var node = new Node();
AddChild(node);
}v5.0.0:
[Test]
public void MyLogicTest()
{
// Runs fast without Godot runtime
var result = Calculator.Add(1, 2);
AssertThat(result).IsEqual(3);
}
[Test]
[RequireGodotRuntime] // ← Add this for Godot-dependent tests
public void MyGodotTest()
{
var scene = new PackedScene();
var node = scene.Instantiate();
AddChild(node);
}
[Test]
[RequireGodotRuntime]
[GodotExceptionMonitor] // ← Monitor Godot exceptions
public void TestNodeCallback()
{
var node = new MyNode(); // Will catch exceptions in _Ready()
AddChild(node);
}
[Test]
[DataPoint(nameof(TestData))] // ← Data-driven tests
public void TestCalculations(int a, int b, int expected)
{
AssertThat(Calculator.Add(a, b)).IsEqual(expected);
}
[Test]
[ThrowsException(typeof(ArgumentNullException), "Value cannot be null")]
public void TestValidation()
{
Calculator.Add(null, 5); // Expects specific exception
}
// Data source for parameterized tests
public static IEnumerable<object[]> TestData => new[]
{
new object[] { 1, 2, 3 },
new object[] { 5, 7, 12 }
};Performance Impact 🚀
- Non-Godot tests: Up to 10x faster execution
- CI/CD friendly: No Godot installation required for logic tests
- Selective runtime: Only pay the Godot overhead when needed
Key Attribute Features 🏷️
Data-Driven Testing
[Test]
[DataPoint(nameof(CalculationData))]
public void TestCalculations(int a, int b, int expected)
{
AssertThat(Calculator.Add(a, b)).IsEqual(expected);
}
// Multiple data source options
public static IEnumerable<object[]> CalculationData => new[]
{
new object[] { 1, 2, 3 },
new object[] { 5, 7, 12 }
};
// Parameterized data methods
[DataPoint(nameof(GetDynamicData), 10)]
public static IEnumerable<object[]> GetDynamicData(int multiplier) =>
Enumerable.Range(1, 3).Select(i => new object[] { i * multiplier });
// External data sources
[DataPoint(nameof(SharedTestData), typeof(TestDataProvider))]
public void TestWithExternalData(string input, bool expected) { }Exception Testing
// Basic exception type verification
[Test]
[ThrowsException(typeof(ArgumentNullException))]
public void TestNullArgument() { }
// Message validation
[Test]
[ThrowsException(typeof(InvalidOperationException), "Operation not allowed")]
public void TestSpecificError() { }
// File and line verification
[Test]
[ThrowsException(typeof(ArgumentException), "Invalid value", "Calculator.cs", 25)]
public void TestPreciseLocation() { }
// Multiple possible exceptions
[Test]
[ThrowsException(typeof(ArgumentNullException))]
[ThrowsException(typeof(ArgumentException))]
public void TestMultipleExceptions() { }Godot Integration
// Class-level runtime requirement
[RequireGodotRuntime]
public class NodeTests
{
[Before]
public void Setup() => Engine.PhysicsTicksPerSecond = 60;
}
// Method-level monitoring
[Test]
[RequireGodotRuntime]
[GodotExceptionMonitor]
public void TestNodeBehavior()
{
var node = new MyCustomNode();
AddChild(node); // Will catch exceptions in _Ready(), _Process(), etc.
}.runsettings Configuration
<RunSettings>
<GdUnit4>
<CaptureStdOut>true</CaptureStdOut>
<Parameters>--verbose --headless</Parameters>
<DisplayName>FullyQualifiedName</DisplayName>
<CompileProcessTimeout>30000</CompileProcessTimeout>
</GdUnit4>
</RunSettings>Summary
This release represents a major step forward in making GdUnit4 more efficient, flexible, and suitable for modern development workflows. The selective runtime approach allows developers to get the best of both worlds: lightning-fast tests for business logic and full Godot integration when needed.
Key Benefits:
- ⚡ Performance: Up to 10x faster for non-Godot tests
- 🧪 Data-Driven: Comprehensive parameterized testing with multiple data source options
- 🔍 Exception Testing: Precise exception validation with message and location verification
- 🎮 Godot Integration: Smart runtime detection and exception monitoring
- 🛠️ VSTest Compatible: Full integration with Visual Studio and
dotnet test
For technical support and questions, please visit our GitHub repository or documentation.
What's Changed
✨ New Features
- GD-138: Add capture test case execution stdout to the test report by @MikeSchulze in #139
- GD-144: Add AwaitInputProcessed to SceneRunner by @MikeSchulze in #145
- GD-46: Added support of DataPoint attributes, which make it possible to define parameterized tests with dynamic test data by @MikeSchulze in #147
- GD-153: Add Roslyn Analyzer to validate TestCase and DataPoint attribute combinations by @MikeSchulze in #154
- GD-156: Add an exception hook to report exceptions as test failures that are caught by Godot by @MikeSchulze in #157
- GD-160: Apply runsettings environment variables to the test execution context by @MikeSchulze in #161
- GD-163: Collect the Godot log file into test report by @MikeSchulze in #164
- GD-156: Install Godot exception handler and forward uncaught exceptions as test failure. by @MikeSchulze in #162
- GD-682: Rework on GdUnit4Net API Godot bridge by @MikeSchulze in #197
- GD-27: Add VSTest filter support with test categories and traits by @MikeSchulze in #201
- GD-240: Add
GDUNIT4NET_API_V5Conditional Compilation Constant by @MikeSchulze in #241 - Upgrade to .NET 8/9 with C# 12 support by @MikeSchulze in #267
- GD-211: Implement missing
AwaitSignalOnby @MikeSchulze in #282
🪲 Bug Fixes
- GD-149: Add error to the execution log when the test session timeout occurs by @MikeSchulze in #150
- GD-152: Fix test case display name for dynamic test data driven tests by @MikeSchulze in #176
- Fixes Godot exception monitoring issues by @MikeSchulze in #187
- Make
WithTimeoutpublic by @MikeSchulze in #189 - GD-199: TestRunner install ends with abnormal exit on large projects by @MikeSchulze in #200
- GD-203: Handle failure reporting for test stages [Before] and [After] by @MikeSchulze in #204
- GD-212: Fix vector assertion
IsEqualApproxby @MikeSchulze in #214 - GD-284: Fix test failure causes the entire test execution if it is executed in the Godot Editor by @MikeSchulze in #285
🧹 Maintenance
- GD-140:
GdUnit4 API:code cleanup and formatting by @MikeSchulze in https://github.com/MikeSchulze/gdUni...
gdUnit4Net v4.3.1
Hot Fix
What's Changed
- GD-135: Allow to use
AssertSignalonRefCountedObjects by @MikeSchulze in #136
Full Changelog: v4.3.0...v4.3.1
gdUnit4Net v4.3.0
Major Changes
The way test events are sent has been changed from std:out to IPC and had to be updated in the API and test adapter.
With this version, we achieve the test adapter in Rider to debugging without need of hacks.
It is important to update Rider to 2024.2 or later to enable the test adapter to run debug.
gdUnit4.api v4.3.0
gdUnit4.test.adapter v2.0.0
What's Changed
- GD-127: Replace stdout based TestEventProcessor by IPC implementation by @MikeSchulze in #129
- GD-124: Use
LaunchProcessWithDebuggerAttachedinstead ofAttachDebuggerIfNeedfor Rider 2024.2 by @MikeSchulze in #130
Full Changelog: v4.2.5...v4.3.0
gdUnit4Net v4.2.5
What's Changed
gdUnit4.api v4.2.5
- GD-110: Allow a Node to be passed in to SceneRunner.Load as the root of the scene. by @taylor-nightingale in #111
- GD-121: Improve
AssertSignalby adding aStartMonitoringmethod by @MikeSchulze in #122
gdUnit4.test.adapter v1.1.2
- GD-114: Fix test adapter
gdUnit4.apiversion resolving by @MikeSchulze in #118 - GD-115: Fix Debug tests gets stuck when using
--verboseby @MikeSchulze in #119
Other changes
- GD-116: Add publish WF to publish test reports in a separate way by @MikeSchulze in #120
- GD-87: Remove temporary solution of
Godot.SourceGenerators.MustBeVariantAnalyzerwarnings by @MikeSchulze in #123
New Contributors
- @taylor-nightingale made their first contribution in #111
Full Changelog: v4.2.4...v4.2.5
gdUnit4Net v4.2.4
gdUnit4.apiv4.2.4gdUnit4.test.adapterv1.1.1
Improvements
- GD-89: Add input action support to the
SceneRunnerby @MikeSchulze in #92 - GD-94: Improve assertions error message when comparing objects by @MikeSchulze in
Bug fixes
- GD-90: Cleanup old runner configuration before run new tests by @MikeSchulze in #93
#95 - GD-96: Fix methods with a single parameterized test case are not executed by @MikeSchulze in #97
- Use example project for unit test using gdunit4-action by @MikeSchulze in #98
- GD-99: Add support to load a scene by
uid://path to the Scene Runner by @MikeSchulze in #100 - GD-101: Respect the GdUnit4 settings to notify about orphan nodes by @MikeSchulze in #102
- GD-103: Trim MSTest assert stack trace by @MikeSchulze in #105
- GD-104: Fix exception failure message propagation by @MikeSchulze in #108
Full Changelog: v4.2.3...v4.2.4
gdUnit4Net v4.2.3
gdUnit4.apiv4.2.3gdUnit4.test.adapterv1.1.1
What's Changed
gdUnit4.api
- GD-84: Fix
AssertThatfor dynamic assert type resolving by @MikeSchulze in #85
gdUnit4.test.adapter
- GD-86: Fixes space in folder name prevents tests from running by @MikeSchulze in #88
New Contributors
- @AdamLearns made their first contribution in #83
Full Changelog: v2.2.2...v4.2.3
gdUnit4Net v4.2.2
GdUnit4Net Release Notes
gdUnit4.apiv4.2.2gdUnit4.test.adapterv1.1.0
What's Changed
- GD-6: Update project to GodotSharp v4.1.0 by @MikeSchulze in #7
- GD-9: Fix SceneRunnerTest by @MikeSchulze in #13
- GD-5: SceneRunner: Fix InputEvent handling by @MikeSchulze in #14
- GD-12: Reorganize the project by @MikeSchulze in #15
- GD-11: Add continue integration tests for pull request by @MikeSchulze in #23
- GD-11: Fix CI workflow by @MikeSchulze in #24
- GD-16: Add GdUnit4 Test Adapter to CI Workflow by @MikeSchulze in #25
- GD-40: Fix GdUnit4MonoAPI
IsTestSuitecannot run TestSuite by @MikeSchulze in #41 - GD-42: Fix test run stops at some point by @MikeSchulze in #43
- GD_35: Add example to show usage of
gdUnit4.test.adapterby @MikeSchulze in #37 - G-8: Provide generic vector assert to support all Godot vector types by @MikeSchulze in #45
- GD-51: Format and fix warnings according to C# standards by @MikeSchulze in #53
- GD-54: Format the tests according to the C# Formatting rules by @MikeSchulze in #55
- GD-52: Format the code to C# standard by @MikeSchulze in #56
- GD-357: Parameterized test cases are not run from Godot Editor GdUnit4 inspector by @MikeSchulze in #59
- Support both net7 and net8 at once by @van800 in #61
- GD-62: Add full .NET8 support by @MikeSchulze in #63
- GD-22: Calling Invoke on
SceneRunnermust propagate exceptions by @MikeSchulze in #65 - GD-49: Revision of the stack trace collection for failed tests by @MikeSchulze in #66
- GD-10: Complete missing features for
IDictionaryAssertby @MikeSchulze in #67 - GD-10: Complete missing features for
IEnumerableAssertby @MikeSchulze in #69 - GD-10: Complete missing features for
INumberAssertby @MikeSchulze in #70 - GD-32: Add missing
SimulateMouseMoveRelativeandSimulateMouseMoveAbsolutetoISceneRunnerby @MikeSchulze in #71 - GD-26: Fix parameterized tests are incorrect grouped by @MikeSchulze in #73
- GD-74: Improve the CI workflow for job
unit-test-exampleby validate the test report by @MikeSchulze in #75 - GD-76: Fix
DisplayNameresolving on test adapter by @MikeSchulze in #79 - GD-80: Rename repository from
gdUnit4MonotogdUnit4Netby @MikeSchulze in #81
New Contributors
- @MikeSchulze made their first contribution in #7
- @van800 made their first contribution in #61
Full Changelog: v2.3.1...v2.2.2