BioErrorLog Tech Blog

試行錯誤の記録

Rustでparameterized testを書く | rstest

rstestを使ってparameterized test/パラメータテストを書く方法を整理します。

はじめに

Rustでは、parameterized testを実装する機能はデフォルトでは提供されていません。

Pythonのpytestに慣れた身としては、Rustでもparameterized testを書きたい気持ちがあります。

今回はそのやり方をまとめます。

Rustでparameterized testを書く

選択肢

Rustでparameterized testを書くやり方には、ざっと調べただけでもいくつか選択肢があります。

  • macroで書く
  • test-caseを利用して書く
  • rstestを利用して書く

まず、外部crateに頼らないのであればmacroで書くやり方があります。 外部crateを利用する場合は、test-caserstestが人気そうです。

test-caseはparameterized testを実装するためのテストツールです。 rstestはpytestに似たfixtureベースのテストフレームワークで、parameterized testもサポートされています。

今回は、より用途も広く使えそうなrstestを使ってみます。

GitHub starの推移を見てもrstestの方がより安定して人気がありそうです:

GitHub starの推移 | star-historyより

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も活用してより良い開発者体験を享受していきたいところです。

[関連記事]

www.bioerrorlog.work

www.bioerrorlog.work

www.bioerrorlog.work

参考

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).

GitHub Star History

Unit testing in Rust - are there no parameterized tests or expectations? : rust