godotengine/godot
Testing
Test framework
Godot's C++ unit tests use doctest (vendored under thirdparty/doctest). The harness lives in:
tests/test_main.cpp— entry point invoked byMain::test_entrypointwhen--testis passed.tests/test_main.h— wires registration of every test file.tests/test_macros.h— domain-specific macros built on top of doctest'sTEST_CASE/SUBCASE/CHECK/REQUIRE.
Where tests live
Tests are organized by area:
tests/
├── core/ Core engine tests (Object, Variant, math, IO, OS, templates, …)
├── scene/ Scene tree + node tests
├── servers/ Server-level tests (rendering doesn't have many unit tests because it needs a GPU)
├── compatibility_test/ Backwards-compatibility tests
├── data/ Test fixtures (PNG, JSON, GLTF samples, …)
├── display_server_mock.cpp A mock DisplayServer used so tests can run headless
├── signal_watcher.{cpp,h} Helper for asserting signal emissions
├── test_utils.{cpp,h} Setup/teardown helpers
└── test_macros.h Macros for parameterized + GDScript-aware testsModule-specific tests live under modules/<name>/tests/ and are pulled in via the module's SCsub when tests=yes. The biggest module test suite is modules/gdscript/tests/, which has ~600 GDScript-level tests covering parser, analyzer, and VM behaviour.
Adding a test
Build with tests=yes:
scons platform=linuxbsd target=editor tests=yes dev_build=yesCreate a new test file (the helper script tests/create_test.py can scaffold one):
// tests/core/math/test_vector3.h
#pragma once
#include "core/math/vector3.h"
#include "tests/test_macros.h"
namespace TestVector3 {
TEST_CASE("[Vector3] Basics") {
Vector3 v(1, 2, 3);
CHECK(v.x == 1);
CHECK(v.length_squared() == 14);
}
}Then #include "tests/core/math/test_vector3.h" from tests/test_main.cpp (or the module-local equivalent). Recompile and run:
./bin/godot.linuxbsd.editor.x86_64 --headless --test --test-case='[Vector3]*'doctest's filter syntax accepts wildcards on test case names.
Headless and DisplayServerMock
Most tests run with DisplayServer == DisplayServerHeadless (no window). UI tests that need a viewport use tests/display_server_mock.cpp, a DisplayServer that provides a buffer surface without an OS window — useful for Control tests that need a Viewport size + theme without rendering pixels.
GDScript tests
modules/gdscript/tests/ contains:
- A
.gdfile (the test). - A
.outfile (the expected stdout). - An optional
.cfgfor parser-only / analyzer-only / runtime-only mode.
The test runner compiles and executes the .gd, captures stdout, and diffs it against .out. Update files atomically when changing language behaviour.
CI
GitHub Actions in .github/workflows/ run on every PR:
- Static checks: pre-commit (clang-format, clang-tidy, ruff, mypy), doc coverage, header guards, file naming.
- Linux: GCC + Clang builds (editor + templates) with the test suite.
- Windows: MSVC builds (editor + templates) — tests where applicable.
- macOS: Apple Clang builds.
- Android, iOS, Web: editor and template builds.
The static-check job is the fastest signal that something is wrong.
Fuzzing and stress
Some areas use ad-hoc fuzz harnesses that sit outside the main test runner:
modules/gdscript/tests/parser_fuzzer.cpp— feeds random byte sequences to the parser.- The image / scene loaders have a corpus under
tests/data/that the suite exercises against the loader.
There is no continuous fuzzing infrastructure built into this repo; OSS-Fuzz integration is occasionally proposed but not yet landed.
Manual / project-based testing
For changes that affect rendering, audio, physics, or UI feel, contributors typically pair unit tests with a Minimal Reproduction Project demonstrating before/after behaviour. The Godot Demos repo (godotengine/godot-demo-projects) has standard scenes you can reuse.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.