【Rust】がばがばRust独学 - 11. Tests - 3 Test Organization
Rustの公式ドキュメントを通して、Rustを独学していく記事になります。(がば要素あり)
今回も、Testについて学びつつ、気になった点をコード確認した結果を記事にしています。
- versions
$ rustc --version rustc 1.40.0 (73528e339 2019-12-16)
Test Organization
Test Organization - The Rust Programming Language
両方の種類のテストを作成することが、ライブラリを期待通りに動作させるために重要とのことです。
- unit tests (ユニットテスト)
- integration tests (統合テスト)
Unit Tests
#[cfg(test)]
アノテーションは cargo test
時にのみ実行され、 cargo build
時には実行されないため、Integration Testsに比べてコンパイルタイムが短縮可能です。
また、private functionについてもテストすることが可能です。
pub fn add_two(a: i32) -> i32 { internal_adder(a, 2) } fn internal_adder(a: i32, b: i32) -> i32 { a + b } #[cfg(test)] mod tests { use super::*; #[test] fn internal() { assert_eq!(4, internal_adder(2, 2)); } }
running 1 test test tests::internal ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Integration Tests
tests/xxx.rs
としてテストを記述することが可能です。
これにより、ライブラリのパブリックAPIのテストが可能になります。
例えば、公式ドキュメントのデモコード(Test Organization - The Rust Programming Language)を利用した場合、
use demo_test_organization; #[test] fn it_adds_two() { assert_eq!(4, demo_test_organization::add_two(2)); }
$ cargo test Finished test [unoptimized + debuginfo] target(s) in 0.00s Running target/debug/deps/demo_test_organization-ead944c9e6e8c86e running 1 test test tests::internal ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out Running target/debug/deps/integration_test-dc19df7dcdc5b51f running 1 test test it_adds_two ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out Doc-tests demo_test_organization running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
上記のようにテストすることが可能です。
また、Integration Testの単一テストファイルだけをテストしたい場合は、 --test
オプションを利用することによって実行可能です。
$ cargo test --test integration_test Finished test [unoptimized + debuginfo] target(s) in 0.00s Running target/debug/deps/integration_test-dc19df7dcdc5b51f running 1 test test it_adds_two ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
テスト時のサブモジュール
テスト用のサブモジュールを利用する場合、サブモジュールとして tests/common.rs
のように直下に配置してしまった場合は、 cargo test
の中に含まれてしまいます。
そのため、 tests/common/mod.rs
としてモジュール化し、
mod common;
と対象のテストファイルに記述することによって、サブモジュールとしての利用が可能になります。
まとめ
- unit tests (ユニットテスト)
src/lib.rs
などsrc
に記述し、#[cfg(test)]
アノテーションを利用可能
- integration tests (統合テスト)
tests
配下にファイルを格納することによってテストが可能- サブモジュール利用の場合は、
test/xxx/mod.rs
とすることによってモジュール可能mod xxx;
をテストコードに記述することにより、モジュールを利用可能
最後に
Unit Testによって、srcが長くなってしまいそうだなぁというのが正直な感想です。
ただ、他言語の場合、単体テストが乱雑に配置されるパターンも往々にあるため、単体テストがしやすい状態ではあるかもしれないです。
大規模開発になった場合、ビジネスロジックが肥大化して、さらに単体テストで圧迫するなどが考えられますね・・・
次回は、I/Oになります。