| name | runtime-test |
| description | Run Godot scenes with runtime testing via command-line flags. Set properties, call methods, emit signals, capture signals, and assert expectations—all without editing source files. |
Runtime Test - CLI Testing Framework for Godot
Test Godot scenes at runtime without modifying source files. Perfect for:
- AI agents running automated tests
- CI pipeline integration
- Quick debugging and state injection
- Signal capture and assertion
Grep-First Design
All output uses [RT:*] prefix for easy filtering:
godot ... 2>&1 | grep "\[RT:"
grep "\[RT:PASS\]"
grep "\[RT:FAIL\]"
grep "\[RT:OK\]"
grep "\[RT:ERR\]"
grep "\[RT:SIGNAL\]"
grep "\[RT:RESULTS\]"
Quick Reference
Injection Commands
--set:Path:prop=value
--call:Path:method:arg1
--emit:Path:signal:arg1
Observation Commands
--print:Path:prop
--listen:Path:signal
--watchprop:Path:prop
Assertion Commands
--expect:Path:prop=value
--expect-signal:Path:sig
--expect-signal:Path:sig:a:b
--expect-no-signal:Path:sig
Control Commands
--wait:500
--wait-frames:10
--watch
Path Conventions
. = scene root
Player = direct child
Player/Health = nested path
Basic Usage
godot --path . --headless scene.tscn -- --set:.:health=50 --expect:.:health=50
godot --path . scene.tscn -- --watch --watchprop:.:state
Key: -- separates Godot flags from RuntimeTest flags.
Examples
Property Testing
godot --path . --headless scene.tscn -- \
--set:.:health=50 \
--expect:.:health=50
Signal Testing
godot --path . --headless scene.tscn -- \
--listen:.:health_changed \
--call:.:take_damage:30 \
--expect-signal:.:health_changed
Assert Signal NOT Emitted
godot --path . --headless scene.tscn -- \
--listen:.:died \
--set:.:health=100 \
--call:.:take_damage:10 \
--expect-no-signal:.:died
Async Testing with Wait
godot --path . --headless scene.tscn -- \
--listen:.:animation_finished \
--call:.:play_death \
--wait:500 \
--expect-signal:.:animation_finished
Watch Mode (Interactive)
godot --path . scene.tscn -- \
--watch \
--watchprop:.:state \
--set:.:debug=true
Output Markers
| Marker | Meaning |
|---|
[RT:OK] | Operation succeeded |
[RT:ERR] | Operation failed |
[RT:PASS] | Assertion passed |
[RT:FAIL] | Assertion failed |
[RT:PRINT] | Property printed |
[RT:CHANGE] | Watched property changed |
[RT:SIGNAL] | Signal captured |
[RT:WAIT] | Waiting |
[RT:WATCH] | Watch mode info |
[RT:RESULTS] | Summary/system message |
Exit Codes
0 = All assertions passed
1 = One or more assertions failed
Type Parsing
| Input | Parsed As |
|---|
true/false | bool |
123 | int |
1.5 | float |
IDLE | enum (looked up in script) |
| anything else | String |
CI Pipeline Integration
godot --path . --headless scene.tscn -- \
--set:.:health=50 \
--expect:.:health=50
if [ $? -ne 0 ]; then
echo "Tests failed!"
exit 1
fi
godot ... 2>&1 | grep -q "\[RT:FAIL\]" && exit 1
Common Patterns
State Machine Testing
godot --path . --headless scene.tscn -- \
--listen:.:state_changed \
--call:.:transition_to:ATTACKING \
--expect-signal:.:state_changed
Damage System Testing
godot --path . --headless scene.tscn -- \
--listen:.:health_changed \
--listen:.:died \
--set:.:health=100 \
--call:.:take_damage:150 \
--expect:.:health=0 \
--expect-signal:.:died
XR Scene Testing
godot --path . --xr-mode on scene.tscn -- \
--watch \
--set:.:debug_mode=true
Troubleshooting
[RT:ERR] property not found
- Check spelling
- Verify property exists in script
- Check node path
[RT:ERR] wrong arg count
- Method expects different number of arguments
- Check method signature
[RT:FAIL] signal not listening
- Add
--listen:Path:signal BEFORE the action that emits
- Order matters: listen → trigger → assert
[RT:OK] set ... (coerced from X)
- Type was converted (e.g., float→int truncation)
- Value was accepted but modified
Instructions for Claude
When user asks to test a scene:
- Use
--headless for automated tests
- Listen before triggering:
--listen must come before actions that emit
- Assert after actions:
--expect comes after --set/--call
- Use exit codes for CI: non-zero = failure
- Grep output for filtering:
grep "\[RT:FAIL\]"
Example:
godot --path . --headless Scenes/Player.tscn -- \
--listen:.:health_changed \
--set:.:health=50 \
--expect:.:health=50 \
--expect-signal:.:health_changed