JUnit5の@ParameterizedTestでテストの表示名を整える

## はじめに
[ひとりJUnitアドベントカレンダー](https://qiita.com/advent-calendar/2022/junit)5日目の記事です。
クロアチア戦見ながら書こうと思ったのに全然進まなくて困った。日本代表お疲れ様でした。

## `@ParameterizedTest`実行時のテスト名は元々いい感じ
そうなんです。デフォルトでもややいい感じなんです。
例えば、`@ValueSource`で`String`を受け取って暗黙の型変換する時は以下のような表示。

```java
  @ParameterizedTest
  @ValueSource(strings = {"Bob", "Tom"})
  void test(Student student) {
    System.out.println(student);
  }
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541075/97629833-54b5-8951-c5b4-b3c2635f3c03.png)
テストのindexと、その時に引数で渡される値が並んでいますね。

引数二つ＋`@MethodSource`の時は以下のような表示です。

```java
  @ParameterizedTest
  @MethodSource("studentProvider")
  void test(Student student, int number) {
    System.out.println(student);
    System.out.println(number);
  }

  static Stream<Arguments> studentProvider() {
    return Stream.of(
        arguments(new Student("Bob"), 25),
        arguments(new Student("John"), 30)
    );
  }
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541075/df9bbf64-90f1-741a-0aa8-d116ea724d24.png)
indexと`toString()`した結果が表示されます。
`toString()`をLombokなどで実装していない場合は`クラス名@hashCode`が出ます。

## さらにいい感じになるポテンシャル
秘めていなくもないです。正直デフォルトのままで十分感はありますが。

上の画像で`test(Student, int)`と表示されている部分は`@DisplayName`、
`[1] Student(name=Bob), 25`と表示されている部分は`@ParameterizedTest`で、
それぞれ表示内容を指定できます。

また、`@ParameterizedTest`で指定する方では以下の変数も使えます。
|`{}`の中に入れる文字|表示内容|
|:--|:--|
|`index`|そのテストが繰り返し中の何番目のテストか(1始まり)|
|数字|そのテストに渡される第(n+1)引数|
|`arguments`|そのテストに渡される引数をカンマ区切りで結合したもの|

説明だとわかりにくいので実例ですが、
以下のように二つのアノテーションに値を渡してみます。

```java
  @DisplayName("DisplayNameに設定した値はここに表示")
  @ParameterizedTest(name = "index -> {index}, 数字 -> {0}, arguments -> {arguments}")
  @MethodSource("studentProvider")
  void test(Student student, int number) {
    System.out.println(student);
    System.out.println(number);
  }
```
実行結果は以下の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541075/f7de99bc-2aa5-1d2e-5a0f-97344eac282d.png)
`{index}`はテストのindex、`{数字}`は引数の内容、
`{arguments}`は全引数に、それぞれ置き換えられています。

正直、ある程度の可読性は引数の変数名やテストメソッド名で担保してほしいと思うので、
この機能の活用にどれほどの情熱を傾けるかはそれはそれで考える余地がありそうですが、
例として以下のケースを考えてみます。
```java
  @ParameterizedTest
  @CsvSource(value = {"152, 10, 200", "2635, 100, 3000", "4239, 10, 4200"})
  void roundTest(int base, int target, int expected) {
    assertThat(hogeService.round(base, target), is(expected));
  }
```

`round`という言葉の通り、四捨五入を行う処理のテストです。
こちらのテスト、デフォルトでの実行結果は以下になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541075/1dde786b-df70-ecf0-1a79-e695f912233d.png)
まあ確かに、これだけでは何をやってるのかさっぱりわかりません。

そこで、ちょっと記述はゴテゴテしますが、
以下のようにアノテーションをふんだんに活用してみると・・・
```java
  @DisplayName("四捨五入のテスト")
  @ParameterizedTest(name = "ケース{index} {0}を{1}の位で四捨五入すると{2}になること")
  @CsvSource(value = {"152, 10, 200", "2635, 100, 3000", "4239, 10, 4200"})
  void roundTest(int base, int target, int expected) {
    assertThat(hogeService.round(base, target), is(expected));
  }
```
実行結果はこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541075/c9c28af0-32c5-c414-f416-d3ba3a1926ea.png)
よくわかりますね。

別で作ったテストケースがあってそれと見比べたいとか、
何かしらのテスト記録をどこかしらに提出しないといけないとか、
常に広く使えるというわけではないものの、特定の場面では結構輝きそうな気がしました。

IDEで見ている分には恩恵を感じなかったためあまり推していませんでしたが、
CI/CDの通知のような、実際に落ちたテストコードをすぐに参照できず、
どのテストが落ちたのかを少量の情報から端的に知りたい場面では有用かもしれません。