AndroidでもJUnit4が使えるようになったことで、parametarized testingも容易に可能になったのか確認してみました。
例
端末のローケルを設定し、その情報を取得する関数を確認するためのテストです。
コード
import android.content.Context;
public class LocaleUtils {
// eg: ja_JP
public String getLocale(Context context) {
return context.getResources().getConfiguration().locale.toString();
}
}
テストコード
複数のローケルを設定した上で、正常に設定したローケルを取得できるか?というテストを愚直に書くと以下のようになります。
public class LocaleUtilsTest {
private Context context;
private Configuration config;
@Before
public void setLocales() {
context = InstrumentationRegistry.getTargetContext();
config = context.getResources().getConfiguration();
}
@Test
public void getJpLocaleDisplayNameTest() {
locale_jp = Locale.JAPAN;
config.setLocale(locale_jp);
assertThat(new LocaleUtils().getLocaleDisplayName(context), is(locale_jp.getDisplayName()));
}
@Test
public void getEnLocaleDisplayNameTest() {
locale_en = Locale.ENGLISH;
config.setLocale(locale_en);
assertThat(new LocaleUtils().getLocaleDisplayName(context), is(locale_en.getDisplayName()));
}
}
これ、多言語化が進むなどでlocalの設定する種類が増えると、そのぶんコピペのテストケースが増え、必要以上に冗長になります。
そこで、parametarized testです。
Parametarized test
JUni4におけるParametarized Testの細かな構文説明はここでは除きます。
ポイントはざっと以下です。
- RunWithでTheories.classを指定する
- ただ、本来はTheoriesは組み合わせテスト用…
- @DataPoint / @DataPointsでパラメータ化する要素をまとめる
- @Theoryにテストケースを書く
- @Testは使いません
@RunWith(Theories.class)
public class LocaleUtilsTestWithParameterized {
private static Context context;
private static Configuration config;
public static class LocalSettingParameter {
Locale locale;
LocalSettingParameter(Locale locale) {
this.locale = locale;
}
}
@DataPoints
public static LocalSettingParameter[] SETTINGS = {
new LocalSettingParameter(Locale.JAPAN),
new LocalSettingParameter(Locale.ENGLISH),
new LocalSettingParameter(Locale.FRENCH)
};
@Before
public void setUp() {
context = InstrumentationRegistry.getTargetContext();
config = context.getResources().getConfiguration();
}
@Theory
public void getLocaleSettingsTest(LocalSettingParameter setting) {
config.setLocale(setting.locale);
assertThat(new LocaleUtils().getLocale(context),
is(setting.locale.toString()));
}
}
これにより、DataPointsを増やすだけでテストケースを増やすことが可能になります。
このDataPoint/DataPointsはBeforeが解釈される前に計算されるので、Beforeで設定した値を動的に入れるということはできません。
ちなみに、@Testとしてアノテーションを設定したら、通常のテストケースとして処理が行われます。
@Theoryは複数作っても良いので、たとえばLocalSettingParameterにより変わるテストケースを1つのファイルに集めて分散を防ぐとかもできます。
Androidのテスト、だいぶんまとめやすくなりましたね。
1 Comment