Install Asset
Install via Godot
To maintain one source of truth, Godot Asset Library is just a mirror of the old asset library so you can download directly on Godot via the integrated asset library browser
Quick Information
Out-of-process E2E testing tool for Godot.Test your Godot games from Python using pytest. The addon runs a TCP automation server as an Autoload β completely dormant unless launched with the --e2e flag.Features:- Synchronous Python API (no async/await needed)- Input simulation: keyboard, mouse, named actions- Node operations: get/set properties, call methods, group lookup- Frame synchronization: wait for process/physics frames or game time- Scene management: change scene, reload scene- Screenshot capture with pytest failure integration- Works with standard Godot 4.x binaries, no engine modificationsInstall the Python package: pip install godot-e2eDocumentation: https://github.com/RandallLiuXin/godot-e2e/tree/main/docs
English | δΈζ
godot-e2e
Out-of-process E2E testing tool for Godot
Quick Start
1. Install the addon
Copy addons/godot_e2e/ into your Godot project's addons/ directory. Add AutomationServer
as an Autoload in your project settings:
- Path:
*res://addons/godot_e2e/automation_server.gd - Name:
AutomationServer
The * prefix means the script is used directly (not a scene). The server is completely dormant
unless the game is launched with the --e2e flag, so it has no effect in production builds.
2. Install the Python package
pip install godot-e2e
Or install from source:
pip install -e .
3. Write a test
from godot_e2e import GodotE2E
def test_player_moves(game):
initial_x = game.get_property("/root/Main/Player", "position:x")
game.press_action("move_right")
game.wait_physics_frames(10)
new_x = game.get_property("/root/Main/Player", "position:x")
assert new_x > initial_x
Run:
pytest tests/ -v
Features
- Out-of-process β game runs in a separate process; crashes are isolated and timeouts are safe
- No engine modifications β works with standard Godot 4.x binaries
- Synchronous Python API β no async/await required in test code
- Input simulation β keyboard, mouse clicks, named actions
- Node operations β get/set properties, call methods, group lookup, node existence checks
- Frame synchronization β wait for process frames, physics frames, or game time
- Scene management β change scene, reload scene
- Screenshot capture β manual or automatic on test failure (pytest integration)
- pytest fixtures β built-in fixtures with configurable test isolation strategies
How It Works
Two processes communicate over a local TCP connection:
- Python (pytest) β sends JSON-encoded commands and waits for responses
- Godot (AutomationServer) β an Autoload that listens on a TCP port, executes commands on the main thread, and sends back results
The AutomationServer only opens its socket when the game is started with --e2e (and
optionally --e2e-port <port>). In normal play or exported builds without that flag, the autoload
does nothing.
pytest ββββ TCP (localhost) ββββ AutomationServer (Godot Autoload)
sends: {"cmd": "get_property", "path": "/root/Main/Player", "prop": "position:x"}
gets: {"ok": true, "value": 400.0}
pytest Fixtures
Three isolation strategies are available depending on your needs.
Strategy 1: reload_scene (default, fast)
Reloads the current scene between each test. Cheap and usually sufficient.
# conftest.py
import pytest
from godot_e2e import GodotE2E
GODOT_PROJECT = "/path/to/your/project"
@pytest.fixture(scope="module")
def _game_process():
with GodotE2E.launch(GODOT_PROJECT) as game:
game.wait_for_node("/root/Main", timeout=10.0)
yield game
@pytest.fixture(scope="function")
def game(_game_process):
_game_process.reload_scene()
_game_process.wait_for_node("/root/Main", timeout=5.0)
yield _game_process
Strategy 2: game_fresh (strongest isolation)
Launches a brand new Godot process for each test. Slowest but fully isolated.
@pytest.fixture(scope="function")
def game_fresh():
with GodotE2E.launch(GODOT_PROJECT) as game:
game.wait_for_node("/root/Main", timeout=10.0)
yield game
Strategy 3: Shared session (fastest)
One process for the entire test session. Use when tests are carefully ordered and do not share mutable state.
@pytest.fixture(scope="session")
def game_session():
with GodotE2E.launch(GODOT_PROJECT) as game:
game.wait_for_node("/root/Main", timeout=10.0)
yield game
CI Configuration
Linux (GitHub Actions, headless via Xvfb)
- name: Install Godot
run: |
wget -q https://github.com/godotengine/godot-builds/releases/download/4.4-stable/Godot_v4.4-stable_linux.x86_64.zip
unzip -q Godot_v4.4-stable_linux.x86_64.zip
sudo mv Godot_v4.4-stable_linux.x86_64 /usr/local/bin/godot
- name: Run E2E tests
run: |
pip install -e .
xvfb-run --auto-servernum pytest tests/e2e/ -v
Windows (GitHub Actions)
- name: Install Godot
run: |
Invoke-WebRequest -Uri "https://github.com/godotengine/godot-builds/releases/download/4.4-stable/Godot_v4.4-stable_win64.exe.zip" -OutFile godot.zip
Expand-Archive godot.zip -DestinationPath C:\godot
shell: pwsh
- name: Run E2E tests
run: |
pip install -e .
pytest tests/e2e/ -v
env:
GODOT_BIN: C:\godot\Godot_v4.4-stable_win64.exe
macOS (GitHub Actions)
- name: Install Godot
run: |
wget -q https://github.com/godotengine/godot-builds/releases/download/4.4-stable/Godot_v4.4-stable_macos.universal.zip
unzip -q Godot_v4.4-stable_macos.universal.zip
sudo mv "Godot.app" /Applications/Godot.app
- name: Run E2E tests
run: |
pip install -e .
pytest tests/e2e/ -v
env:
GODOT_BIN: /Applications/Godot.app/Contents/MacOS/Godot
Set GODOT_BIN to override the default Godot executable path. The default search order is:
godot4, godot, then platform-specific standard locations.
API Reference
Launch / Lifecycle
| Method | Description |
|---|---|
GodotE2E.launch(project_path, **kwargs) |
Context manager. Launches Godot and returns a connected GodotE2E instance. |
game.close() |
Terminate the Godot process and close the connection. |
Node Operations
| Method | Description |
|---|---|
game.node_exists(path) |
Returns True if the node at path exists in the scene tree. |
game.wait_for_node(path, timeout=5.0) |
Blocks until the node exists or timeout is reached. |
game.get_property(path, prop) |
Get a property value. Supports dotted paths like "position:x". |
game.set_property(path, prop, value) |
Set a property value on a node. |
game.call_method(path, method, *args) |
Call a method on a node and return the result. |
game.find_by_group(group) |
Return a list of node paths for all nodes in the given group. |
Input Simulation
| Method | Description |
|---|---|
game.press_action(action) |
Press and immediately release a named input action. |
game.input_action(action, pressed) |
Set a named input action pressed state. |
game.key_press(scancode) |
Press and release a key by scancode. |
game.mouse_click(x, y, button=1) |
Click a mouse button at the given screen coordinates. |
Frame Synchronization
| Method | Description |
|---|---|
game.wait_frames(n) |
Wait for n process (_process) frames to complete. |
game.wait_physics_frames(n) |
Wait for n physics (_physics_process) frames to complete. |
game.wait_seconds(t) |
Wait for t in-game seconds (affected by Engine.time_scale). |
Scene Management
| Method | Description |
|---|---|
game.change_scene(scene_path) |
Change to a scene by res:// path. |
game.reload_scene() |
Reload the current scene. |
Diagnostics
| Method | Description |
|---|---|
game.screenshot(path=None) |
Capture a screenshot. Returns PNG bytes; saves to path if given. |
Examples
| Example | Description |
|---|---|
| minimal | Simplest setup β node checks, property reading, method calls (3 tests) |
| platformer | Player movement, scoring, groups, scene reload (5 tests) |
| ui_testing | Button clicks, label verification, scene navigation (5 tests) |
Run any example:
cd examples/minimal
pytest tests/e2e/ -v
License
Apache 2.0. See LICENSE.
Out-of-process E2E testing tool for Godot.
Test your Godot games from Python using pytest. The addon runs a TCP automation server as an Autoload β completely dormant unless launched with the --e2e flag.
Features:
- Synchronous Python API (no async/await needed)
- Input simulation: keyboard, mouse, named actions
- Node operations: get/set properties, call methods, group lookup
- Frame synchronization: wait for process/physics frames or game time
- Scene management: change scene, reload scene
- Screenshot capture with pytest failure integration
- Works with standard Godot 4.x binaries, no engine modifications
Install the Python package: pip install godot-e2e
Documentation: https://github.com/RandallLiuXin/godot-e2e/tree/main/docs
Reviews
Quick Information
Out-of-process E2E testing tool for Godot.Test your Godot games from Python using pytest. The addon runs a TCP automation server as an Autoload β completely dormant unless launched with the --e2e flag.Features:- Synchronous Python API (no async/await needed)- Input simulation: keyboard, mouse, named actions- Node operations: get/set properties, call methods, group lookup- Frame synchronization: wait for process/physics frames or game time- Scene management: change scene, reload scene- Screenshot capture with pytest failure integration- Works with standard Godot 4.x binaries, no engine modificationsInstall the Python package: pip install godot-e2eDocumentation: https://github.com/RandallLiuXin/godot-e2e/tree/main/docs