VSCodeでRustの特定のテストのみを実行できなかった問題

# 特定のテストのみを実行したい
VSCodeにRustの公式extensionを入れてコードを書くと、`#[test]`アトリビュートが付いた関数の上に次のようにボタンが出現して、そのテストを実行できるようになる。

```shell
cargo new my-test --lib
code my-test
```


```rust:src/lib.rs
#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        let result = 2 + 2;
        assert_eq!(result, 4);
    }
}
```
![スクリーンショット 2022-05-01 15.14.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250433/e0465263-06bc-1dc0-51bd-f8f26703f8c9.png)

この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]`が付いた関数の名前である。例えば、

```rust:src/lib.rs
#[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`を含む全てのテストが実行されてしまう。その結果、

```rust:lib/src.rs
#[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を上げてる人がいるようだが、なぜか全く進んでいない

https://github.com/rust-lang/vscode-rust/issues/864

# cargo testで特定のテストのみを実行する方法
実はcargoではちゃんと特定のテストのみを実行する方法があって、次のように関数名を指定すれば良い。

```shell
cargo test -- --exact tests::it_works
```

https://stackoverflow.com/questions/54585804/how-to-run-a-specific-unit-test-in-rust

に書いてあった。ということは、vscodeでも、Run testを押したときに、`cargo test test_name`じゃなくて、このようにexactオプションをつけて実行してくれればよさそうである。困っている人は同様にいそうなので、自分で実装してプルリクを送れば貢献にはなりそうだが、vscode extensionの作り方を勉強するのはまた大変そうなので、またいつかということにした。

# 解決策
というのも、簡単な解決策を見つけてしまったからである。The Rust Programming Languageが作っているextensionじゃなくて、[rust-analyzer](https://marketplace.visualstudio.com/items?itemName=matklad.rust-analyzer)というのを入れると、
![スクリーンショット 2022-05-01 15.40.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250433/bc271a53-a9c5-67db-8444-392ccbfee9d2.png)
このようにボタンが変わり、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.
```
と、ちゃんとそのテストだけが実行される。めでたしめでたし。