目次
Rustは最初からテストが利用可能
#[cfg(test)]
mod tests {
#[test]
fn test_calc() {
assert_eq!(2, 1+1);
}
}
#[cfg(test)]は条件付きコンパイルでテストの時のみコンパイルされます。
#[test]はそれがテストコードであることをしまします。
以下でテストを実行します。
$ cargo test
running 1 test
test tests::test_calc ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
標準出力を出す
テストでは通常、標準出力は出ません。
#[cfg(test)]
mod tests {
#[test]
fn test_calc() {
println!("Hello World!");
assert_eq!(2, 1+1);
}
}
nocaptureオプションをつけると出ます。最初の--はcargoのオプションでは無く、testのオプションを示すための区切り文字です。
$ cargo test -- --nocapture
running 1 test
Hello World!
test tests::test_calc ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
またはshow-output。こちらの方が見やすいです。
$ cargo test -- --show-output
running 1 test
test tests::test_calc ... ok
successes:
---- tests::test_calc stdout ----
Hello World!
successes:
tests::test_calc
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
テストを外す
#[ignore]で外せます
#[cfg(test)]
mod tests {
#[test]
#[ignore]
fn test_calc() {
assert_eq!(2, 1+1);
}
}
$ cargo test
running 1 test
test tests::test_calc ... ignored
test result: ok. 0 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
逆にignoreだけテストすることも可能です。例えば重い処理やローカルでは動かないテストは#[ignore]にしてCIなどでのみテストさせます。
$ cargo test -- --ignored
running 1 test
test tests::test_calc ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out
指定のテストだけ実行
テストの引数に文字列をつけると、その文字列にマッチしたテストだけ実行されます。ここは--はいらないです。
#[cfg(test)]
mod tests {
#[test]
fn test_calc1() {
assert_eq!(2, 1+1);
}
#[test]
fn test_calc2() {
assert_eq!(3, 2+1);
}
}
$cargo test
running 2 tests
test tests::test_calc1 ... ok
test tests::test_calc2 ... ok
$ cargo test 2
running 1 test
test tests::test_calc2 ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out
シングルスレッドで動作
テストは複数スレッドを使って実行されます。しかしDBアクセスなど共通リソースにアクセスするテストでは実行する順番によっては失敗する可能性があります。実行するスレッド数を1にすることで、防ぐことができます。ちなみに無指定の時は何スレッドで動作するかわかりませんでした。多分CPUのコア数と同じなんだと思います。
cargo test -- --test-threads=1
async/awaitのテスト
async/awaitを使った場合通常の#[test]ではコンパイルできません。async/awaitの実行環境が無いと動かないので、ここではtokioを使ってテストします。
[package]
name = "calc"
version = "0.1.0"
edition = "2018"
[dev-dependencies]
tokio = {version="~0.2", features=["macros", "rt-core"]}
async fn acalc(a: i64, b: i64) -> i64 {
if a > b {
a - b
} else {
a + b
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_calc() {
assert_eq!(2, acalc(5, 3).await);
}
}