Charaken 技術系ブログ

技術系に関して学んだことや、気になったことを記事にしていく。

【Rust】がばがばRust独学 - 11. Tests - 2 Controlling How Tests Are Run

f:id:charaken:20191223210559p:plain

Rustの公式ドキュメントを通して、Rustを独学していく記事になります。(がば要素あり)

doc.rust-lang.org

今回も、Testについて学びつつ、気になった点をコード確認した結果を記事にしています。

  • versions
$ rustc --version
rustc 1.40.0 (73528e339 2019-12-16)


Controlling How Tests Are Run

公式ドキュメント:Controlling How Tests Are Run - The Rust Programming Language

デモコード: github.com

コマンドラインオプションには2種類存在します。

  • cargo test --helptest に対してのヘルプ
  • cargo test -- --helptest により生成されたテストバイナリにかかるヘルプ

テストバイナリの並列実行数の変更

例えば、各テストに依存関係がある場合、1つずつテストしたい場合があります。

そのため、threads数を1として並列実行させないようにすることも可能です。

$ cargo test -- --test-threads=1

関数出力の表示

公式ドキュメントのデモコード通りに実行すると、エラーのテストの println!("I got the value {}", a); 出力されません。

fn prints_and_returns_10(a: i32) -> i32 {
    println!("I got the value {}", a);
    10
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn this_test_will_pass() {
        let value = prints_and_returns_10(4);
        assert_eq!(10, value);
    }

    #[test]
    fn this_test_will_fail() {
        let value = prints_and_returns_10(8);
        assert_eq!(5, value);
    }
}
running 2 tests
test tests::this_test_will_pass ... ok
test tests::this_test_will_fail ... FAILED

failures:

---- tests::this_test_will_fail stdout ----
I got the value 8
thread 'tests::this_test_will_fail' panicked at 'assertion failed: `(left == right)`
  left: `5`,
 right: `10`', src/lib.rs:19:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.


failures:
    tests::this_test_will_fail

test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

しかし、 --nocapture を利用する事によって、エラーのテストに対してもアウトプットされ利用になります。

$ cargo test -- --nocapture
running 2 tests
I got the value 8
I got the value 4
thread 'tests::this_test_will_fail' panicked at 'assertion failed: `(left == right)`
  left: `5`,
 right: `10`', src/lib.rs:20:9test tests::this_test_will_pass ... 
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
ok
test tests::this_test_will_fail ... FAILED

failures:

failures:
    tests::this_test_will_fail

test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

テスト名を引数として単一テストやフィルタリング

下記のような関数名を利用した場合、テスト名は this_test_will_pass となります。

#[test]
fn this_test_will_pass()

この時、 this_test_will_pass を引数として渡すと、単一テストが可能です。

$ cargo test this_test_will_pass
running 1 test
test tests::this_test_will_pass ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out

また、

$ cargo test this_

として実行した場合、 this_ から始まるテストを実施することが可能です。

running 2 tests
test tests::this_test_will_pass ... ok
test tests::this_test_will_fail ... FAILED

failures:

---- tests::this_test_will_fail stdout ----
I got the value 8
thread 'tests::this_test_will_fail' panicked at 'assertion failed: `(left == right)`
  left: `5`,
 right: `10`', src/lib.rs:20:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.


failures:
    tests::this_test_will_fail

test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

一部テストの無視

#[ignore] を利用することで、通常テストの実行時にはテスト項目から除外することが可能です。

    #[test]
    #[ignore]
    fn expensive_test() {
        // code that takes an hour to run
    }
running 3 tests
test tests::expensive_test ... ignored
test tests::this_test_will_pass ... ok
test tests::this_test_will_fail ... FAILED

failures:

---- tests::this_test_will_fail stdout ----
I got the value 8
thread 'tests::this_test_will_fail' panicked at 'assertion failed: `(left == right)`
  left: `5`,
 right: `10`', src/lib.rs:20:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.


failures:
    tests::this_test_will_fail

test result: FAILED. 1 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out

除外したテストのみ実施したい場合は

$ cargo test -- --ignored

によって実行可能です。

ちなみに、除外有無関係無しに実行できるオプションがあるのですが、死にます。

$ cargo test -- --include-ignored
error: The "include-ignored" flag is only accepted on the nightly compiler

下記については、issueに上がっていますね。

github.com

確かに、 -Zunstable-options オプションを付けるとよしなに動いてくれますね・・・

$ cargo test -- --include-ignored -Zunstable-options
running 3 tests
test tests::expensive_test ... ok
test tests::this_test_will_pass ... ok
test tests::this_test_will_fail ... FAILED
...

まとめ

  • -- のセパレータによってオプション対象を分けられる
    • cargo test --help
    • cargo test -- --help
  • テストバイナリへのオプションは様々ある
    • --test-threads
    • --nocapture
    • --ignored
  • テストから除外したい場合は #[ignore] を利用する

最後に

他のオプションも試してみたいですね。

今回作成したデモコードに #![allow(dead_code)] がございますが、こちらは、メインで prints_and_returns_10 を利用していないがために、しつこくWarningが出ていたためつけております。

github.com

オプション周りがしっかりしているの、良いですね。 --include-ignored はオプションなしで動いてほしいですね・・・

次回もテストの残り部分を進めます!