AndroidJUnit4RunnerでParameterized Test

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のテスト、だいぶんまとめやすくなりましたね。

Advertisements

One thought on “AndroidJUnit4RunnerでParameterized Test

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s