UI Testing
Purpose
UI testing verifies that the Godot user interface responds correctly to researcher interactions.
The Virtual Rodent project separates simulation logic from interface panels, so UI tests focus on controls, visible state changes and emitted user-intent signals rather than directly testing the simulation kernel.
The current UI tests exercise the actual Godot panel scenes in headless mode.
This provides automated evidence that important user-facing controls behave correctly without requiring the full application to be opened manually.
Test structure
The UI test file is:
tests/test_ui.gd
The tests instantiate the real panel scenes used by the application:
src/app/panels/simulation_controls_panel.tscn
src/app/panels/recording_panel.tscn
The tests then interact with the actual controls contained in those scenes.
This includes Godot UI components such as:
- buttons;
- checkboxes;
- option buttons;
- sliders;
- labels; and
- replay controls.
Scene initialization
Godot scenes use lifecycle methods such as _ready() and @onready references.
For this reason, the UI tests add the scene to the active scene tree and wait for a frame before interacting with its controls.
The test flow is:
Instantiate panel | v Add panel to SceneTree | v Wait for process frame | v _ready() completes | v UI controls become available | v Perform UI test
This ensures that controls and signal connections are fully initialized before assertions are made.
Simulation controls testing
The simulation controls panel is tested for the main researcher controls used during a simulation.
The current automated UI tests verify:
- start;
- pause;
- step;
- reset;
- random seed behaviour; and
- simulation speed selection.
Start and pause controls
The Start button is tested in both idle and running states.
The test verifies that:
- the button initially displays
Start; - pressing the button emits
start_requested; - the button changes to
Pausewhen the panel is updated to a running state; and - pressing the button while running emits
stop_requested.
This confirms that the same visible control correctly represents both starting and pausing a simulation.
Step control
The Step button is tested separately.
The automated test verifies that:
- the button exists;
- the button displays the expected text; and
- pressing it emits
step_requested.
This confirms that researchers can request a single simulation step through the UI.
Reset control
The Reset button is tested together with the random seed option.
The test verifies that the New seed on reset checkbox is enabled by default.
The test then performs two reset actions.
With randomization enabled:
Randomize enabled | v Reset | v reset_requested(true)
With randomization disabled:
Randomize disabled | v Reset | v reset_requested(false)
This confirms that the state selected by the researcher is correctly passed from the interface to the application.
Simulation speed testing
The simulation speed selector is tested using the real OptionButton control.
The UI is expected to provide four speed settings:
1x10x100xMax
The automated test verifies:
- all four options are present;
- their visible labels are correct;
- selecting
100xemits the expected speed request; and - selecting
Maxemits the application's internal maximum-speed mode.
This confirms that the user-visible speed controls are correctly translated into application commands.
Recording and replay testing
The recording panel contains controls for viewing results and loading previously saved replays.
The automated tests verify both display state and replay interactions.
Replay mode
The recording panel normally displays run results.
The test verifies that its initial state contains Run results and that the replay library is hidden.
When replay mode is enabled, the test verifies that:
- the title changes to
Replay library; - replay controls become visible;
- JSON export controls are hidden;
- CSV export controls are hidden; and
- the save replay control is hidden.
This confirms that the panel presents the correct controls for the selected workflow.
Replay library
The replay selector is tested using controlled replay metadata.
The test provides a saved replay entry containing:
Sprint 2 test replay user://replays/test_replay.json
The test verifies that:
- the replay appears in the selector;
- the correct replay label is displayed;
- the load button becomes enabled; and
- pressing the load button emits
load_replay_requestedwith the correct replay path.
This verifies that the UI correctly converts a user replay selection into an application request.
Replay playback controls
Replay playback controls are tested after a replay containing five frames is loaded.
The test verifies that:
- the replay start button becomes enabled;
- the next-frame button becomes enabled;
- the restart button becomes enabled;
- the progress slider represents frame indexes correctly; and
- the replay position label initially displays the first frame.
The playback buttons are then tested individually.
Start replay
Pressing the replay start control must emit:
replay_start_requested
Pause replay
When the replay is marked as running, the visible button text must change to:
Pause replay
Pressing the button must emit:
replay_pause_requested
Next frame
Pressing the next-frame control must emit:
replay_step_requested
Restart
Pressing the restart control must emit:
replay_restart_requested
Replay position display
The replay UI also displays the current position within a recorded run.
The test provides:
- frame index:
2; - total frames:
5; and - simulation time:
1.25 seconds.
The interface must update to:
Frame 3 of 5 | 1.25 s
The progress slider must also move to frame index 2.
This verifies that replay state is represented correctly in the UI.
Automated UI test coverage
The current UI tests cover six main workflows:
Simulation Controls | +-- Start +-- Pause +-- Step +-- Reset +-- Randomize seed +-- Speed selection
Recording and Replay | +-- Replay mode +-- Replay library +-- Replay loading +-- Start replay +-- Pause replay +-- Next replay frame +-- Restart replay +-- Replay progress display
The current automated UI suite therefore tests both interaction behaviour and visible interface state.
Running the UI tests
The UI tests are executed using Godot in headless mode.
From the project root:
godot4 --headless --path . --script tests/test_ui.gd
A successful run produces output similar to:
PASS: start and pause controls PASS: step control PASS: reset control PASS: simulation speed picker PASS: replay library and loading PASS: replay playback controls
PASS: all UI tests
The process exits successfully only when all UI assertions pass.
Headless UI testing
The UI tests are executed without opening the graphical Godot editor.
Headless testing is useful because it:
- can be run quickly from the terminal;
- is repeatable;
- does not require manual clicking;
- can be included in future continuous integration;
- verifies real Godot scenes and controls; and
- can run together with the existing simulation tests.
The tests still instantiate actual Godot Control nodes even though no window is displayed.
Test isolation
The UI tests focus on panel behaviour and do not require the complete application to start.
For example, the simulation controls tests verify that user actions emit the correct intent signals rather than requiring a full simulation run.
The boundary is:
Researcher action | v Godot UI control | v Panel signal | v Application shell | v Simulation / service logic
The UI test verifies the first part of this boundary.
Simulation and service behaviour are tested separately by the other automated test suites.
This separation makes failures easier to identify and keeps UI tests focused on interface responsibilities.
Why signals are tested
The application panels communicate user intent using Godot signals.
Examples include:
start_requestedstop_requestedstep_requestedreset_requestedspeed_mode_requestedload_replay_requestedreplay_start_requestedreplay_pause_requestedreplay_step_requestedreplay_restart_requested
Testing these signals verifies that pressing a visible control results in the correct request being sent to the rest of the application.
This avoids coupling UI tests directly to the simulation kernel.
Failure handling
If a UI test fails, the developer should determine whether the problem is caused by:
- an incorrect control state;
- a missing signal;
- an incorrect signal value;
- a scene initialization problem;
- an incorrect visible label;
- a disabled control;
- an unintended UI regression; or
- an incorrect automated test.
The relevant test should be rerun after the issue is corrected.
Regression testing
When a UI defect is discovered, an automated UI regression test should be added where practical.
Examples include:
- a button stops emitting its intended signal;
- a replay button remains disabled after loading;
- the wrong simulation speed is emitted;
- replay state is displayed incorrectly; or
- a UI mode displays controls that should be hidden.
This ensures that fixed UI defects do not return unnoticed.
Future UI tests
Additional automated UI tests can be added as other interface features are completed.
Possible future areas include:
- experiment configuration;
- preset selection;
- arena editing;
- environment import;
- validation messages;
- treatment configuration;
- stimulus editing; and
- experiment save/load workflows.
Team members responsible for these panels can extend tests/test_ui.gd or add additional UI test files as required.
AI Attribution: This document was drafted and edited with AI assistance, including ChatGPT and OpenAI Codex. The team reviewed it against the implemented project.