GridPlacement 5.1 (GDScript) — How to Test a Plugin
Scope: GridPlacement / GridBuilding 5.0–5.1 GDScript legacy line.
Policy: 5.1 is maintenance-mode. Prefer small, focused tests. Avoid heavy demo-scene megasuites.
Test Types: What to Write (Decision Rules)
Contract-first testing (behavior, not implementation)
Treat tests as a behavior contract that the runtime must satisfy. This is how we keep tests stable while allowing runtime refactors.
- What tests MUST assert
- Observable outcomes (returned values/results, emitted signals/events, externally visible state).
- Invariants (what must remain true after operations).
- Failure modes (what issues/errors are surfaced for invalid inputs).
- What tests MUST NOT assert
- Internal call order, helper methods, node tree layout specifics, or private implementation details.
- Exact timings/frame counts or micro-optimizations.
If a refactor breaks a test, treat it as contract drift: either behavior changed unintentionally (fix runtime), or the contract changed intentionally (update tests + docs together).
1) Write C# Core unit tests when:
- You can express the behavior as pure logic (math, rules, selection, transforms, state transitions).
- You want fast, deterministic tests with minimal engine dependency.
- The behavior is intended to be canonical for 6.0 and beyond.
Good examples
- Grid coordinate conversion, snapping, bounds checks.
- Rule evaluation logic and validation result objects.
2) Write C# Godot integration (harness-based) tests when:
- The behavior needs Godot types/nodes (TileMap, collisions, signals) but can be exercised in a minimal scene.
- You can avoid loading the full demo.
- You need confidence that runtime wiring works (services + adapters).
Good examples
- Collision probing against a minimal TileMap.
- A placement flow that requires signals/state holders.
3) Write 5.1 GDScript GdUnit smoke tests when:
- The behavior is specific to the legacy addon and realistically won’t be ported immediately.
- You need confidence that the 5.1 addon still works for existing users.
- You can keep the test thin (wiring + a small number of assertions).
Good examples
- Curated Tier-1/Tier-2 addon-level suites.
- Targeting/positioning contracts that are hard to represent without the 5.1 nodes.
Keep Tests Small (Patterns)
Prefer: “minimal harness” setup
- Create only the nodes you need.
- Use a minimal TileMap/scene where applicable.
- Use deterministic inputs (fixed coordinates, fixed tile sizes, fixed seeded randomness if any).
Avoid: “demo megasetup” patterns
- Avoid loading full demo scenes.
- Avoid old
TestEnvironment/mega-harness style tests. - Avoid fragile pixel-assertions unless the feature is explicitly visual.
Acceptance Criteria (What Good Looks Like)
A test is acceptable for the 5.1 curated slice if:
- It runs headless via the standard runner.
- It has deterministic assertions (no timing flakiness).
- It doesn’t require full demo scenes.
- It aligns with the curated KEEP list (or is a clearly justified small addition).
Running Tests (5.1 GdUnit)
Use the runbook from ../../ROADMAP.md.
To validate the 5.1 public/internal boundary (no preload() of class_name scripts), run the canonical check from the game_dev/docs repo:
| |
Validation entrypoints (post-shim cleanup)
As a low-impact breaking change, several unused GBCompositionContainer validation shims were removed.
When writing tests or diagnostics, use the authoritative entrypoints instead:
- Runtime issues:
composition_container.get_runtime_issues() - Structure issues:
composition_container.get_structure_issues() - Injector boolean:
GBInjectorSystem.validate_runtime()
Parameterized Tests (GdUnit4 Canonical Pattern)
GdUnit4 parameterization is done by adding a trailing argument named test_parameters or _test_parameters to the test function.
- Name rule
- Use
test_parametersor_test_parameters. - Prefer
_test_parametersin this repo to avoid warnings-as-errors for an unused argument.
- Use
- Shape rule
- The value must be an
Arrayof parameter rows. - Each row is an
Arraywhose values map 1:1 to the preceding function parameters.
- The value must be an
- Typing rule
- Give the parameter set an explicit type:
_test_parameters: Array = [...].
- Give the parameter set an explicit type:
Example:
| |
Reference implementation:
gdscript/grid_building/test/systems/placement/unit/rule_check_indicator_logic_unit_test.gd