mcpField
T
tui-tests

tui-tests

github.com/gitbutlerappテスト・品質21.9k41 回インストール今日更新
リポジトリ

tui-tests について

`but` のステータス TUI を対象とする Rust テスト用スキルです。既存のハーネス、入力方法、スナップショットによる検証、テストコマンドを開発者向けに説明します。

主な機能

  1. 01TUI テストハーネスの設定
  2. 02キー入力とテキスト入力の再現
  3. 03スナップショットによる描画検証
  4. 04TUI テスト実行のガイド

活用シーン

  1. 01TUI の動作テスト追加
  2. 02カーソルや選択状態の確認
  3. 03テストスナップショットの更新

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/gitbutlerapp/gitbutler --skill tui-tests

インストール後、Claude Code で/tui-testsを入力して読み込まれたか確認します。

詳細

テストの配置場所

  • メインの TUI テスト:crates/but/src/command/legacy/status/tui/tests/
  • テストハーネス/ヘルパー:crates/but/src/tui/test_utils.rs および crates/but/src/command/legacy/status/tui/tests/utils.rs
  • スナップショット:crates/but/src/command/legacy/status/tui/tests/snapshots/

基本パターン

#[test]
fn describes_behavior_under_test() {
    let env = Sandbox::init_scenario_with_target_and_default_settings("one-stack").unwrap();
    env.setup_metadata(&["A"]).unwrap();

    let mut tui = test_status_tui(env);

    tui.input_then_render(KeyCode::Down)
        .assert_rendered_term_svg_eq(file!["snapshots/describes_behavior_under_test_001.svg"]);
}

TUI の操作

入力例:

tui.input_then_render(None);                                       // render without inputs
tui.input_then_render('j');                                        // single char input
tui.input_then_render(KeyCode::Down);                              // special key
tui.input_then_render(Shift('j'));                                 // keys with shift
tui.input_then_render(Control('j'));                               // keys with control
tui.input_then_render([KeyCode::Down, KeyCode::Down]);             // multiple keys from array
tui.input_then_render("commit message text");                      // multiple keys from string
tui.reload();                                                      // reload state after making external changes

アサーション

基本的には、次を使用してください。

  • カーソル/選択の動作には assert_current_line_eq(str![...])。
  • それ以外のすべてには assert_rendered_term_svg_eq(file!["snapshots/test_function_name_001.svg"])。

入力の論理的なグループごとに、assert_rendered_term_svg_eq を 1 つ含めるのが一般的です。これにより、不正な状態を早期に検出できます。

assert_rendered_contains と assert_rendered_not_contains の使用には注意してください。誤検出につながる可能性があります。スナップショットによる変更が多くなりすぎるテストを反復しているときに使うことを想定しています。

より専門的なアサーションについては、crates/but/src/tui/test_utils.rs と crates/but/src/command/legacy/status/tui/tests/utils.rs を参照してください。

crates/but/src/tui/test_utils.rs または crates/but/src/command/legacy/status/tui/tests/utils.rs に新しい種類のアサーションを追加してはいけません。既存のアサーションのみを使用してください。

ほかのテストのスナップショットを再利用しないでください。各テスト専用のスナップショットを用意してください。

t ui.env().invoke_git("...") は使用しないでください。TUI を通じて操作することを優先してください。

テストの実行

  • cargo test -p but <test-name> で、1 つのテストを実行します。
  • SNAPSHOTS=overwrite cargo test -p but <test-name> で、テストを実行してスナップショットを更新します。
  • cargo test -p but tui で、すべての TUI テストを実行します。変更を加えた後に実行してください。

テストが失敗すると、出力にテストバックエンドのレンダリング状態が含まれます。テストを反復する際に、状態を確認するために利用できます。

コメント