Instaって何ですか?
InstaとはRustのスナップショットテスト用クレートです。
PythonのWebフレームワークFlaskの開発者によって開発されました(すごい)。
(公式サイトはこちら: https://insta.rs/)
サンプルコードを実行してみよう
スナップショットテストを実行するための簡単なサンプルコードです。
"Hello, world!"という文字列を返すだけの簡単な関数をテストしています。
fn hello_world() -> String {
String::from("Hello, world!")
}
#[test]
fn test_hello_world() {
insta::assert_snapshot!(hello_world());
}
それではこのサンプルコードをcargo testで実行してみましょう。
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s
テストは失敗してしまいますが、同じ階層にsnapshotsというディレクトリが作成され、その中にスナップショットファイル*.snap.newが作成されています。
---
source: sample_crate/src/sample.rs
assertion_line: 7
expression: hello_world()
---
Hello, world!
期待通り、"Hello, world!"が出力されているようなので、拡張子を*.snapに変更します。
そして改めてcargo testを実行すると、、、
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s
今度は成功しました。
テストを失敗させると*.snap.newが出力されるので、いろいろ試してみてください。
レビューを楽にしよう
cargo-instaをインストールすることで、上記の手順が対話的に実行できるようになります。
差分の確認などがかなり楽になります。
(Cargo Instaのドキュメントはこちら: https://insta.rs/docs/cli/)
それではテストが失敗した状態で、cargo insta reviewコマンドを実行してみましょう。
Reviewing [1/1] sample_crate@0.1.0:
Snapshot file: sample_crate/src/snapshots/sample_crate__sample__hello_world.snap
Snapshot: hello_world.snap
Source: sample_crate/src/sample.rs:7
────────────────────────────────────────────────────────────────────────
Expression: hello_world()
────────────────────────────────────────────────────────────────────────
+new results
────────────┬───────────────────────────────────────────────────────────
1 │+Hello, world!
────────────┴───────────────────────────────────────────────────────────
a accept keep the new snapshot
r reject reject the new snapshot
s skip keep both for now
i hide info toggles extended snapshot info
d hide diff toggle snapshot diff
Tip: Use uppercase A/R/S to apply to all remaining snapshots
差分が表示され、a/r/sでレビューができます。また、ファイルの拡張子も自動で変更してくれます。
便利なglobマクロを利用しよう
入力がファイル形式の処理について考えてみましょう。テストでは複数の入力ファイル用意して、それらを順に読み込ませて結果を確認する必要があります。
そんなときに便利なのがglobマクロです。
#[test]
fn test_() {
glob!("**/*.txt", |path| {
let text = std::fs::read_to_string(path).unwrap();
assert_snapshot!(text.to_uppercase());
});
}
サンプルコードは.txtファイルがすべて大文字に変換されることを確認するテストです。
まとめ
Rustで簡単にスナップショットテストを実装できるInstaの紹介でした。
とても簡単なので、採用してみてはいかがでしょうか。