Google社内ではどのようなテストツールを使っているのか:Javaプログラム用単体テストツール
GoogleはJavaプログラム用単体テストツール「JUnit」を利用する際、自社開発のテストフレームワークを利用している。社内では「JUnit 4」とこのテストフレームワークを組み合わせて利用している。2021年3月にテストフレームワークをオープンソース化しており、2022年9月には他社の開発者向けに「JUnit 5」をサポートした。
Googleは2022年9月7日(米国時間)、Javaプログラム用単体テストツール「JUnit」に対応したオープンソースのパラメーター化テストフレームワーク「TestParameterInjector」で「JUnit 5」(Jupiter)をサポートしたと発表した。
TestParameterInjectorは、もともとGoogleが社内で使っていたものだ。同社は2021年3月に、「JUnit 4」に対応したTestParameterInjectorのオープンソース版を公開している。
Google社内ではJavaプログラムのテストツールに何を使っているのか
それから1年以上を経て、TestParameterInjectorはGoogle社内で利用が急増しており、圧倒的な人気を持つパラメーター化テストフレームワークとなっている。
上図のグラフが示しているように、Google社内ではTestParameterInjectorを用いたパラメーター化テストが急激に増加している。理由は2つある。まず、TestParameterInjectorが通常の単体テストのパラメーター化を容易にしたことだ。次にGooglerがテスト品質向上のために、このツールをより積極的に使用するようになったことだという。
JUnit 5(Jupiter)サポート
Google社内では現在、JUnit 4のみを使用しているが、社外の開発者の一部は、JUnit 5(Jupiter)に移行している。そうした開発者のために、TestParameterInjectorをJUnit 5に対応させた。
次のコードに示すように、APIは可能な限りそのまま維持されている。
// **************** JUnit4 **************** //
@RunWith(TestParameterInjector.class)
public class MyTest {
@TestParameter boolean isDryRun;
@Test public void test1(@TestParameter boolean enableFlag) { ... }
@Test public void test2(@TestParameter MyEnum myEnum) { ... }
enum MyEnum { VALUE_A, VALUE_B, VALUE_C }
}
// **************** JUnit5 (Jupiter) **************** //
class MyTest {
@TestParameter boolean isDryRun;
@TestParameterInjectorTest
void test1(@TestParameter boolean enableFlag) {
// This method is run 4 times for all combinations of isDryRun and enableFlag
}
@TestParameterInjectorTest
void test2(@TestParameter MyEnum myEnum) {
// This method is run 6 times for all combinations of isDryRun and myEnum
}
enum MyEnum { VALUE_A, VALUE_B, VALUE_C }
}
JUnit 4版とJUnit5対応版の違いは、「@RunWith」「@ExtendWith」が不要なことと、全てのテストメソッドに「@TestParameterInjectorTest」のアノテーションが必要なことだ。
TestParameterInjectorの他の機能は、次のコードのようにJUnit 5使用時も同様に動作する。
class MyTest {
// **************** Defining sets of parameters **************** //
@TestParameterInjectorTest
@TestParameters(customName = "teenager", value = "{age: 17, expectIsAdult: false}")
@TestParameters(customName = "young adult", value = "{age: 22, expectIsAdult: true}")
void personIsAdult_success(int age, boolean expectIsAdult) {
assertThat(personIsAdult(age)).isEqualTo(expectIsAdult);
}
// **************** Dynamic parameter generation **************** //
@TestParameterInjectorTest
void matchesAllOf_throwsOnNull(
@TestParameter(valuesProvider = CharMatcherProvider.class) CharMatcher charMatcher) {
assertThrows(NullPointerException.class, () -> charMatcher.matchesAllOf(null));
}
private static final class CharMatcherProvider implements TestParameterValuesProvider {
@Override
public List<CharMatcher> provideValues() {
return ImmutableList.of(
CharMatcher.any(), CharMatcher.ascii(), CharMatcher.whitespace());
}
}
}
Googleが改善を進めるTestParameterInjector
- TestParametersのカスタム名
例えば、次のパラメーター化テストを実行するとしよう。
@Test
@TestParameters("{age: 17, expectIsAdult: false}")
@TestParameters("{age: 22, expectIsAdult: true}")
public void withRepeatedAnnotation(int age, boolean expectIsAdult){ ... }
すると生成されるテスト名は次のようになる。
MyTest#withRepeatedAnnotation[{age: 17, expectIsAdult: false}]
MyTest#withRepeatedAnnotation[{age: 22, expectIsAdult: true}]
このように小さなパラメーターセットでは問題は起きないものの、@TestParametersの数やYAML文字列内のパラメーター数が多くなると、各パラメーターセットが何を表しているのかが分かりにくくなる。
こうした場合のために、「customName」を追加するオプションが追加された。
@Test
@TestParameters(customName = "teenager", value = "{age: 17, expectIsAdult: false}")
@TestParameters(customName = "young adult", value = "{age: 22, expectIsAdult: true}")
public void personIsAdult(int age, boolean expectIsAdult){...}
- RobolectricTestRunnerとの統合
最近、TestParameterInjectorアノテーションをサポートするバージョンの「RobolectricTestRunner」が、Google社内で作成された。だが、これをオープンソース化するにはまだかなりの作業が残っている。Googleは、このバージョンのオープンソース化をいつ、どのように進めるかは、検討中だとしている。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
5分で分かるテスト自動化
現在のソフトウェア開発に欠かせない「テスト自動化」について、およそ5分でざっくり解説します。
基礎から学ぶ、テスト自動化――導入時に見極めたい、コストの損益分岐点
ソフトウェアテストにおける選択肢の一つとして候補に挙がるのが「テスト自動化」だ。本連載では、テスト自動化に取り組みたいけれどノウハウがない、過去に導入していたがうまくいかなくてやめた人に向けて、テスト自動化の「あるある」な失敗事例とともにどうすればうまく取り入れられるのかを解説する。第1回は「テスト自動化とは何か」と「導入時に注意すべきポイント」について。

