Expand description
Pilot testing framework for automated UI tests.
Test your TUI applications with simulated user interactions, assertions on rendered output, and snapshot testing.
§Features
| Feature | Description |
|---|---|
| Key Simulation | Simulate keyboard input |
| Text Search | Assert on rendered text |
| Snapshot Testing | Compare against golden files |
| Visual Regression | Color & style comparison |
| CI Integration | GitHub Actions, GitLab CI |
| Async Support | Test async operations |
| Action Sequences | Chain multiple actions |
§Quick Start
ⓘ
use revue::testing::{Pilot, TestApp};
use revue::event::Key;
#[test]
fn test_counter() {
let mut app = TestApp::new(Counter::new());
let mut pilot = Pilot::new(&mut app);
pilot
.press(Key::Up)
.press(Key::Up)
.assert_contains("Count: 2")
.snapshot("counter_at_2");
}§Pilot API
§Key Simulation
ⓘ
pilot
.press(Key::Enter) // Press Enter
.press(Key::Char('a')) // Type 'a'
.type_text("hello") // Type string
.press(Key::Escape); // Press Escape§Assertions
ⓘ
pilot
.assert_contains("Welcome") // Text exists
.assert_not_contains("Error") // Text doesn't exist
.assert_focused(".input") // Element is focused
.assert_visible(".modal"); // Element is visible§Snapshot Testing
ⓘ
pilot
.snapshot("initial_state") // Save/compare snapshot
.press(Key::Enter)
.snapshot("after_enter");Snapshots are stored in tests/snapshots/ and can be updated with:
REVUE_UPDATE_SNAPSHOTS=1 cargo test§Waiting
ⓘ
pilot
.wait_ms(100) // Wait 100ms
.wait_until(|screen| { // Wait for condition
screen.contains("Loaded")
});§TestApp
TestApp wraps your view for testing:
ⓘ
use revue::testing::{TestApp, TestConfig};
// Default 80x24 terminal
let app = TestApp::new(MyView::new());
// Custom size
let config = TestConfig {
width: 120,
height: 40,
..Default::default()
};
let app = TestApp::with_config(MyView::new(), config);§Action Sequences
Build reusable action sequences:
ⓘ
use revue::testing::{ActionSequence, Action};
let login_sequence = ActionSequence::new()
.action(Action::Type("admin".into()))
.action(Action::Press(Key::Tab))
.action(Action::Type("password".into()))
.action(Action::Press(Key::Enter));
pilot.run_sequence(&login_sequence);§Async Testing
For testing async operations:
ⓘ
use revue::testing::AsyncPilot;
#[tokio::test]
async fn test_async_load() {
let app = TestApp::new(MyAsyncView::new());
AsyncPilot::run(app, |pilot| async move {
pilot.press(Key::Enter).await;
pilot.wait_until_async(|s| s.contains("Loaded")).await;
pilot.assert_contains("Data loaded");
}).await;
}§Visual Regression Testing
For pixel-perfect UI testing with color and style comparison:
ⓘ
use revue::testing::{VisualTest, VisualTestConfig};
#[test]
fn test_button_styles() {
let test = VisualTest::new("button_normal")
.group("buttons");
let buffer = render_my_widget();
test.assert_matches(&buffer);
}Update golden files:
REVUE_UPDATE_VISUALS=1 cargo test§CI Integration
Detect CI environments and generate reports:
ⓘ
use revue::testing::{CiEnvironment, TestReport};
let ci = CiEnvironment::detect();
let mut report = TestReport::new();
// Run tests...
report.add_passed("button_test");
report.add_failed("modal_test", "Size mismatch");
// Generate CI-specific output
report.write_summary(&ci);
report.save_artifacts(&ci).ok();§Best Practices
- Name snapshots descriptively:
"login_form_with_error"not"test1" - Test user flows: Simulate realistic user interactions
- Keep tests focused: One behavior per test
- Use wait_until for async: Don’t rely on fixed delays
- Use visual tests for styling: Catch color and layout regressions
- Run in CI: Use
CiEnvironmentfor portable test reports
Re-exports§
pub use mock::capture_render;pub use mock::mock_alt_key;pub use mock::mock_click;pub use mock::mock_ctrl_key;pub use mock::mock_key;pub use mock::mock_mouse;pub use mock::mock_terminal;pub use mock::mock_time;pub use mock::simulate_user;pub use mock::EventSimulator;pub use mock::MockState;pub use mock::MockTerminal;pub use mock::MockTime;pub use mock::RenderCapture;pub use mock::SimulatedEvent;pub use visual::CapturedCell;pub use visual::CellDiff;pub use visual::VisualCapture;pub use visual::VisualDiff;pub use visual::VisualTest;pub use visual::VisualTestConfig;pub use visual::VisualTestResult;pub use ci::CiEnvironment;pub use ci::CiProvider;pub use ci::TestReport;pub use ci::TestResult;
Modules§
- ci
- CI integration helpers for visual regression testing
- mock
- Mocking utilities for testing Revue applications
- visual
- Visual regression testing for TUI applications
Structs§
- Action
Sequence - A sequence of actions that can be replayed
- Async
Pilot - Async test runner for Pilot
- Pilot
- Pilot controller for automated testing
- Snapshot
Manager - Snapshot manager for storing and comparing test snapshots
- TestApp
- A test application that can run views without a real terminal
- Test
Config - Test configuration
Enums§
- Action
- A recorded test action
- Assertion
Result - Result of an assertion
- KeyAction
- Key-related actions
- Mouse
Action - Mouse-related actions
Traits§
- Assertion
- An assertion that can be run against a buffer