Skip to main content

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:

  1. the button initially displays Start;
  2. pressing the button emits start_requested;
  3. the button changes to Pause when the panel is updated to a running state; and
  4. 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:

  • 1x
  • 10x
  • 100x
  • Max

The automated test verifies:

  • all four options are present;
  • their visible labels are correct;
  • selecting 100x emits the expected speed request; and
  • selecting Max emits 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_requested with 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_requested
  • stop_requested
  • step_requested
  • reset_requested
  • speed_mode_requested
  • load_replay_requested
  • replay_start_requested
  • replay_pause_requested
  • replay_step_requested
  • replay_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.