rstestを使ってparameterized test/パラメータテストを書く方法を整理します。
はじめに
Rustでは、parameterized testを実装する機能はデフォルトでは提供されていません。
Pythonのpytestに慣れた身としては、Rustでもparameterized testを書きたい気持ちがあります。
今回はそのやり方をまとめます。
Rustでparameterized testを書く
選択肢
Rustでparameterized testを書くやり方には、ざっと調べただけでもいくつか選択肢があります。
まず、外部crateに頼らないのであればmacroで書くやり方があります。
外部crateを利用する場合は、test-case
やrstest
が人気そうです。
test-case
はparameterized testを実装するためのテストツールです。
rstest
はpytestに似たfixtureベースのテストフレームワークで、parameterized testもサポートされています。
今回は、より用途も広く使えそうなrstest
を使ってみます。
GitHub starの推移を見てもrstest
の方がより安定して人気がありそうです:
rstestでparameterized test
まずはrstest
をdev-dependenciesに追加します。
cargo add --dev rstest
実際のテストコードを書くには、下記のようにします。
pub fn add(left: usize, right: usize) -> usize { left + right } #[cfg(test)] mod tests { use super::*; use rstest::rstest; #[rstest] #[case(0, 0, 0)] #[case(1, 1, 2)] #[case(2, 1, 3)] #[case(3, 2, 5)] #[case(4, 3, 7)] fn parametrized_works(#[case] left: usize, #[case] right: usize, #[case] expected: usize) { let result = add(left, right); assert_eq!(result, expected); } }
#[case(0, 0, 0)]
のようにして入力パラメータを用意し、テスト関数の引数に#[case]
注釈を付けて渡します。
cargo test
結果も、それぞれのパラメータ分がちゃんと表示されます。
$ cargo test # 中略 test tests::parametrized_works::case_1 ... ok test tests::parametrized_works::case_2 ... ok test tests::parametrized_works::case_3 ... ok test tests::parametrized_works::case_4 ... ok test tests::parametrized_works::case_5 ... ok test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
より詳細な使い方は、rstestのドキュメントを参照ください。
おわりに
以上、rstestを使ってparameterized testを書く方法を簡単にまとめました。
Rustはデフォルトのまますぐテストコードが書けて快適ですが、crateも活用してより良い開発者体験を享受していきたいところです。
[関連記事]
参考
unit testing - How can I create parameterized tests in Rust? - Stack Overflow
GitHub - la10736/rstest: Fixture-based test framework for Rust
GitHub - frondeus/test-case: Rust procedural macro attribute for adding test cases easily
GitHub - foresterre/parameterized: 🐑 JUnit style parameterized testing for Rust
GitHub - BurntSushi/quickcheck: Automated property based testing for Rust (with shrinking).
Unit testing in Rust - are there no parameterized tests or expectations? : rust