Skip to content

Testing with insta snapshots

スナップショット テストを使用すると、参照値を 1 回キャプチャして、今後のすべてのテスト実行で使用することで、正確なテストを作成する面倒なプロセスを省略できます。instacargo-insta を使用して、Ratatui アプリとウィジェットのスナップショット テストを簡単に作成できます。

1. 依存関係を追加する

まず、 Cargo.toml にcargo-instaをインストールしてください。

Terminal window
cargo install cargo-insta
cargo add insta --dev

2. アプリケーションの構造化

TUI のコア ロジックとレンダリングを担当する App 構造体を実装するシンプルなアプリケーションがあると仮定します。これをインスタント スナップショットでテストするには、Ratatui の TestBackend を使用して、テスト環境で出力をキャプチャします。

アプリとテストの構造は次のとおりです。

#[derive(Default)]
pub struct App { /* Your app struct */ }
impl Widget for App { /* Implement the Widget trait */ }
// Now in tests module:
#[cfg(test)]
mod tests {
use super::App;
use insta::assert_snapshot;
use ratatui::{backend::TestBackend, Terminal};
#[test]
fn test_render_app() {
let app = App::default();
let mut terminal = Terminal::new(TestBackend::new(80, 20)).unwrap();
terminal
.draw(|frame| frame.render_widget(&app, frame.area()))
.unwrap();
assert_snapshot!(terminal.backend());
}
}

3. テストの実行

テスト (cargo test) を実行すると、Terminal::draw() メソッドの出力がスナップショットと比較されます。初めてテストを実行する場合、または出力が変更された場合は、insta によって snapshots/ ディレクトリの下にスナップショット ファイルが作成されます。

たとえば、テストを実行した後、新しいスナップショットファイルが次のように作成される場合があります。

snapshots/demo2__tests__render_app.snap

このファイルは、ターミナルの視覚的表現を文字列として保存します。

---
source: examples/demo2/main.rs
expression: terminal.backend()
---
"Ratatui Recipe Email Traceroute Weather "
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄▄███▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄███████▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄█████████▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀████████████▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀ ▀▀▀▀▀▀▀▀▀▀▀▀▀███████████▀▀▀▀▄▄██████▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀ ──────── Ratatui ───────── ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀███▀▄█▀▀████████▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀ - cooking up terminal user ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄▄▄▄▀▄████████████▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀ interfaces
- ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀████████████████▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀███▀██████████▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀ Ratatui is a Rust crate ▀▀▀▀▀▀▀▀▀▀▀▀▀▄▀▀▄▀▀▀█████████▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀ that provides widgets ▀▀▀▀▀▀▀▀▀▀▀▄▀ ▄ ▀▄▀█████████▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀ (e.g. Paragraph, Table) ▀▀▀▀▀▀▀▀▀▄▀ ▀▀ ▀▄▀███████▄▄▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀ and draws them to the ▀▀▀▀▀▀▀▄▀ ▄▄ ▀▄▀█████████▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀ ▀▀▀▀▀▄▀ ▀▀ ▀▄▀██▀▀▀███▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ ▀▄▀▀▀▄██▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄ ▀▄▀█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
" H/← Left L/→ Right K/↑ Up J/↓ Down D/Del Destroy Q/Esc Quit "

スナップショットでは、各ラインはターミナルの行を表し、TUIのレンダリングされた状態をキャプチャします。次回テストを実行すると、出力はこのファイルと比較され、意図しない変更が検出されます。

4. スナップショットの変更の処理

UIの変更が意図的である場合、実行してスナップショットを更新できます。

Terminal window
cargo insta review

このコマンドを使用すると、違いを確認し、必要に応じて新しいスナップショットを受け入れることができます。