Check out our latest project ✨ OpenChapter.io: free ebooks the way its meant to be πŸ“–

GodotE2E

An asset by LIUXIN
The page banner background of a mountain and forest
GodotE2E hero image

Quick Information

0 ratings
GodotE2E icon image
LIUXIN
GodotE2E

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

Supported Engine Version
4.0
Version String
1.0.0
License Version
Apache-2.0
Support Level
community
Modified Date
9 hours ago
Git URL
Issue URL

English | δΈ­ζ–‡

godot-e2e

README CI README PyPI README Python README Godot README License

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:

  1. Python (pytest) β€” sends JSON-encoded commands and waits for responses
  2. 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

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
GodotE2E icon image
LIUXIN
GodotE2E

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

Supported Engine Version
4.0
Version String
1.0.0
License Version
Apache-2.0
Support Level
community
Modified Date
9 hours 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