Internals TUI Testing - NormB/sipnab GitHub Wiki

sipnab tests its TUI at three levels.

Snapshot tests (tests/tui_snapshot_test.rs)

These tests use ratatui's TestBackend to render views to an in-memory buffer. Then they use insta for snapshot comparison.

Running

cargo test --features tui --test tui_snapshot_test

Updating snapshots

Use this when rendering changes intentionally.

  • --accept rewrites the .snap files in place.
  • Stage them in the same commit.
    • That is what keeps CI comparing against the new rendering.
# Run all of these, in order.
cargo insta test --features tui --accept
git add tests/snapshots/

Adding a new snapshot test

  • Create a test function that renders to TestBackend
  • Call insta::assert_snapshot!(buffer_to_string(&terminal))
  • Run cargo insta test --accept to create the initial snapshot
  • Commit the .snap file

State machine tests (tests/tui_state_test.rs)

These tests check App state transitions without rendering. They use App::new_test() and App::handle_key().

cargo test --features tui --test tui_state_test

PTY end-to-end tests (tests/tui_e2e_test.rs)

These tests drive the real binary inside a detached tmux session. They do not use a bare PTY.

  • sipnab's TUI queries the terminal at startup.
    • crossterm emits ESC[6n to read the cursor position.
  • A bare pseudo-terminal has no emulator behind it to answer.
    • So the TUI aborts with cursor position could not be read.
  • tmux is a terminal emulator. It does three things:
    • It answers the query.
    • It provides a real window size.
    • It lets the test send keys and snapshot the screen with capture-pane.
  • These tests are #[ignore] by default.
  • They need tmux on PATH.
cargo test --features tui --test tui_e2e_test -- --ignored

These tests are slower (~2s each). They may be flaky in CI.