Check out our latest project ✨ OpenChapter.io: free ebooks the way its meant to be 📖

Godot .NET Scene-Oriented Unit Test

An asset by thremtopod
The page banner background of a mountain and forest
Godot .NET Scene-Oriented Unit Test hero image

Quick Information

0 ratings
Godot .NET Scene-Oriented Unit Test icon image
thremtopod
Godot .NET Scene-Oriented Unit Test

Godot .NET Scene-Oriented Unit Test (ScOUT) is a framework for writing C# unit tests that run within scenes.Features- Running unit tests within scenes makes it easy to test game logic that depends on engine features (e.g. signals) with minimal stubbing.- Automation with JUnit-style test reports.- Only Godot .NET (C#) is supported.

Supported Engine Version
4.2
Version String
1.1
License Version
MIT
Support Level
community
Modified Date
1 year ago
Git URL
Issue URL

Godot .NET Scene-Oriented Unit Test

Godot .NET Scene-Oriented Unit Test (ScOUT) is a framework for writing C# unit tests that run within scenes.

Features

  • Running unit tests within scenes makes it easy to test game logic that depends on engine features (e.g. signals) with minimal stubbing.
  • Automation with JUnit-style test reports.
  • Only Godot .NET (C#) is supported.

Setup

Installation

Install directly from the Godot Asset Library, or download the latest release directly.

:warning: Make sure that the plugin is enabled in the project settings.

Test Scenes

ScOUT is a scene-oriented test framework, so all unit tests are run within test scenes. A test scene is any scene with a test_runner node in it. The test_runner node has the TestRunner script. To create a test scene:

  • Create a new scene.
  • Add a test_runner.tscn node anywhere in the scene hierarchy.
  • (Optional) Configure test_runner node.

The empty test scene should run without any errors. There is a UI that allows for reloading and running tests. During test execution, this UI is hidden so as not to interfere with the tests.

Test Classes and Methods

When ScOUT runs a test scene, it finds all nodes in the scene with a test class as the node's script. It then runs all test methods for each test class.

The [Test] Attribute

A test class is any class that:

A test method is any method that:

  • Is a non-static member of a test class.
  • Has the [Test] Attribute.
  • Has void return type and takes no parameters.

Assertions

The Assert class is a (static) class with utility methods for checking tests' failure conditions.

When an Assert method fails (i.e. the specified condition is not met) it throws an exception that ScOUT recognizes as meaning a test failure. If a test throws an exception that ScOUT does not recognize, ScOUT will interpret that as a test _error_—to handle expected exceptions, use Assert#Throws and/or Assert#DoesNotThrow.

Running Multiple Test Scenes

Test Scene Runners

Multiple test scenes can be run in series by using a _test scene runner_—this a scene that is configured to run a specific set of test scenes. These can be created manually using test_scene_runner.tscn, but the recommended way is by using the ScOUT editor tab.

When running individual test scenes, the ScOUT UI is active; tests can be reloaded and run multiple times. When running test scene runners, the ScOUT UI is inactive and the program automatically exits after the last test scene has run.

The ScOUT Editor Tab

When the plugin is enabled, a new ScOUT tab is added to the editor, next to Inspector, Node and History. The primary function of the ScOUT tab is to create preconfigured test scene runners.

Option Usage
Test Scene Files Add individual test scene *.tscn files.
Test Scene Directories Add individual directories containing test scene *.tscn files (other file types are ignored).
Verbose Logging Whether to print individual test results to stdout.
Print Test Reports to StdOut Whether to print a JUnit-style test report to stdout.
Export Test Reports Whether (and where) to save a JUnit-style test report file.
Set as main scene for test exports Whether to add the generated test scene runner as the value for Main Scene when exporting project with the gdnetscout feature. Overwrites previous value, if any.
Save As Save new test scene runner with the ScOUT tab's current configuration.

Additional Functionality

Other Attributes

[BeforeEach], [AfterEach], [BeforeAll] and [AfterAll]

These attributes can be added to a method in a test class to run before/after each/all test method. The method must not be a test method, and must be non-static with void return type and no parameters. There can be at most one method with each attribute per test class, and a single method cannot have more than one.

Method Runs On Failure
[BeforeEach] Repeatedly, before each test method. Test method fails.
[AfterEach] Repeatedly, after each test method. Test method fails.
[BeforeAll] Once, before the first test method of the test class. Test class fails.
[AfterAll] Once, after the last test method of the test class. Test class fails.

[Skip]

A test class or test method with the [Skip] attribute will be skipped. Skipped tests are not run, though they are still included in test reports.

Using TestRunner's Utility Methods

The TestRunner class has a number of utility methods that can be called by test methods.

Accessing the Active TestRunner Instance

Every test scene has one test_runner node, and therefore one instance of TestRunner. Any object that extends Godot.Node can access the active TestRunner isntance with the extension method Node#GetTestRunner. If called from an inappropriate context, the method will throw an exception.

Waiting and Delaying Invocation

TestRunner has methods for waiting a single frame, for a fixed amount of time, or for a specified signal. Each method takes an Action as an argument, which is invoked after the waiting is finished.

:warning: Only the TestRunner waits, not the invoking test method. Any code that should not run until after waiting is over must be part of the provided Action.

Method Details Example
TestRunner.WaitFrames Wait the g iven numer of frames, then perform the given Action. TestRunnerTest.WaitFrames
TestRunner.WaitSeconds Wait the given number of seconds, then invoke the given Action. TestRunnerTest.WaitSeconds
TestRunner.WaitForSignal Wait for the given Node to emit a signal of the given name, then invoke the given Action. Fail if signal is not emitted within the given timeout. TestRunnerTest.WaitForSignal

All of these methods can have their invocations chained together by nesting the method calls in Action. See TestRunnerTest.WaitForSignal.

Printing

TestRunner has methods for printing that respect the configured verbosity of test. They delegate to Godot's print methods and handle formatting.

Method Delegates to Example
TestRunner.Print GD.Print this.GetTestRunner().Print("pi is {0:0.####}...", Math.PI); // "pi is 3.1416..."
TestRunner.PrintRich GD.PrintRich this.GetTestRunner().PrintRich("[center]e is {0:0.###}...[/center]", Math.E); // "e is 2.718..."
TestRunner.PrintErr GD.PrintErr this.GetTestRunner().Print("Exception: {0}", e); // "Exception: <stack trace>"

Project Export and Test Automation

In addition to running test scenes and test scene runners directly in the editor, because they are regular Godot scenes, they can be exported using project export. A test scene runner is much better suited for test automation than a test scene.

Creating a ScOUT Export Preset

Create a ScOUT-specific export preset. If exporting for CI, a Linux preset is recommended. Add gdnetscout to Custom in the Features tab. No other ScOUT-specific configuration is required.

The gdnetscout custom feature allows the ScOUT export preset to work without affecting anything non-test-related.

:warning: This requires that the Set as main scene for test exports option was selected in the ScOUT tab when the test scene runner was created. If not, the test scene runner can be recreated using the ScOUT tab.

Automated Testing with GitLab CI

This is a broad overview of how this project uses GitLab CI for automated testing, and is not comprehensive. It assumes some existing knowledge of GitLab CI, Docker and running Godot from the command line.

Create a .gitlab-ci.yml file that does the following:

  • (Optional) Use GitLab container registry to re-use images (see Dockerfile).
  • Use an image that has (or install them):
    • Dotnet.
    • Godot.
  • Download Godot export templates, and move to proper location.
  • Export project using ScOUT-specific export preset.
  • Run exported project in headless mode.
  • Keep the test report in artifacts.reports.junit.

For an example of a project using ScOUT for testing, see this project.

It includes:

  • Multiple test scenes.
  • Utilization of TestRunner helper methods.
  • Automated testing using GitLab CI.

By using Xvfb, it's able to run tests in non-headless mode. This enables automated testing of shaders using ScOUT.

Godot .NET Scene-Oriented Unit Test (ScOUT) is a framework for writing C# unit tests that run within scenes.

Features
- Running unit tests within scenes makes it easy to test game logic that depends on engine features (e.g. signals) with minimal stubbing.
- Automation with JUnit-style test reports.
- Only Godot .NET (C#) is supported.

Reviews

0 ratings

Your Rating

Headline must be at least 3 characters but not more than 50
Review must be at least 5 characters but not more than 500
Please sign in to add a review

Quick Information

0 ratings
Godot .NET Scene-Oriented Unit Test icon image
thremtopod
Godot .NET Scene-Oriented Unit Test

Godot .NET Scene-Oriented Unit Test (ScOUT) is a framework for writing C# unit tests that run within scenes.Features- Running unit tests within scenes makes it easy to test game logic that depends on engine features (e.g. signals) with minimal stubbing.- Automation with JUnit-style test reports.- Only Godot .NET (C#) is supported.

Supported Engine Version
4.2
Version String
1.1
License Version
MIT
Support Level
community
Modified Date
1 year ago
Git URL
Issue URL

Open Source

Released under the AGPLv3 license

Plug and Play

Browse assets directly from Godot

Community Driven

Created by developers for developers