特定のテストのみを実行したい
VSCodeにRustの公式extensionを入れてコードを書くと、#[test]
アトリビュートが付いた関数の上に次のようにボタンが出現して、そのテストを実行できるようになる。
cargo new my-test --lib
code my-test
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
let result = 2 + 2;
assert_eq!(result, 4);
}
}
このRun testボタンをクリックすると、ターミナルが起動して
> Executing task: cargo test -- --nocapture it_works <
Finished test [unoptimized + debuginfo] target(s) in 0.01s
Running unittests (target/debug/deps/my_test-c5b6fb0f304517ca)
running 1 test
test tests::it_works ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests my-test
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Terminal will be reused by tasks, press any key to close it.
と、テストが実行できる。出力の1行目に書いてあるように、このボタンを押すと、
cargo test -- --nocapture it_works
が実行されるようになっている。it_works
は#[test]
が付いた関数の名前である。例えば、
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
let result = 2 + 2;
assert_eq!(result, 4);
}
#[test]
fn this_works_also() {
let result = 2 + 3;
assert_eq!(result, 5);
}
}
としたら、this_works_alsoの上にもRun testが出現し、押すと、
> Executing task: cargo test -- --nocapture this_works_also <
...
と表示され、this_works_alsoをテストしようとしたことがわかる。
ところがこのcargo test
でのテスト名の指定の仕方がやや曲者で、
https://doc.rust-jp.rs/book-ja/ch11-02-running-tests.html#複数のテストを実行するようフィルターをかける
に書いてあるように、cargo test test_name
とすると、test_name
を含む全てのテストが実行されてしまう。その結果、
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
let result = 2 + 2;
assert_eq!(result, 4);
}
#[test]
fn it_works_again() {
let result = 2 + 2;
assert_eq!(result, 4);
}
}
のようになっていると、it_works()の上のRun testボタンを押すと、it_works_again()までテストされてしまう。
> Executing task: cargo test -- --nocapture it_works <
Finished test [unoptimized + debuginfo] target(s) in 0.53s
Running unittests (target/debug/deps/my_test-c5b6fb0f304517ca)
running 2 tests
test tests::it_works_again ... ok
test tests::it_works ... ok
...
なんとかならないのだろうか。extensionのgithubを見ると、まさにこのissueを上げてる人がいるようだが、なぜか全く進んでいない
cargo testで特定のテストのみを実行する方法
実はcargoではちゃんと特定のテストのみを実行する方法があって、次のように関数名を指定すれば良い。
cargo test -- --exact tests::it_works
に書いてあった。ということは、vscodeでも、Run testを押したときに、cargo test test_name
じゃなくて、このようにexactオプションをつけて実行してくれればよさそうである。困っている人は同様にいそうなので、自分で実装してプルリクを送れば貢献にはなりそうだが、vscode extensionの作り方を勉強するのはまた大変そうなので、またいつかということにした。
解決策
というのも、簡単な解決策を見つけてしまったからである。The Rust Programming Languageが作っているextensionじゃなくて、rust-analyzerというのを入れると、
このようにボタンが変わり、it_worksのRun Testを押すと
> Executing task: cargo test --package my-test --lib -- tests::it_works --exact --nocapture <
Finished test [unoptimized + debuginfo] target(s) in 0.00s
Running unittests (target/debug/deps/my_test-c5b6fb0f304517ca)
running 1 test
test tests::it_works ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s
Terminal will be reused by tasks, press any key to close it.
と、ちゃんとそのテストだけが実行される。めでたしめでたし。