Android Test KitのEspressoなどのバージョンがあがってたのでざっと調べた

ちょっと追えていなかったのですがEspresso関連のライブラリが2.1が2015年4月21日に、2.2が2015年5月28日にリリースされたのですね。
ちょっと順に追ってみます。

android-test-kit
release note

内容としては、2.0=>2.1では破壊的な変更が発生したので移行時には注意しましょう、でしょうか。ただ、 ActivityInstrumentationTestCase2 を脱却して、 @Rule ベースでアクティビティの起動/終了が管理されるようになったので、個人的には移行をためらう理由もなく、という感じですね。

そのほか、intentなんかも含め、JUnit4らしく?Ruleベースのテストの周辺環境記述に移り変わってきた感じがします。

from 2.0 to 2.1

  • com.android.support.test:testing-support-lib:0.1com.android.support.test:runner:0.2com.android.support.test:rules:0.2 に分割された
    • Gradleプロジェクトを書き換えると思うのですが、書き換えた後はGradleのキャッシュを飛ばしてあげましょう。依存関係に不整合が生じるときがあります。
  • espressoに以下の新機能が追加されました
    • espresso-intents
      • ActivityTestRule を拡張した IntentsTestRule として、functional UI Testとしてインテントを使えるルールが提供されるようになったらしい
    • espresso-core
      • ViewActions なんかの機能追加
      • CheatSheetも更新されてました
    • rules
      • ActivityTestRule が追加されたことで、 single activityのテストを実施するときにわざわざ ActivityInstrumentationTestCase2 を継承する必要がなくなりました
      • UiThreadRuleUiThreadTestServiceTestRuleのRuleが追加されたので、これもRuleベースでテストをかけそう
        • いい感じですね!!
    • UIAutomator
      • UiDevice#dumpWindowHierarchy() の機能追加

コード書き換え

ActivityTestRuleが追加されたことで、いままで致し方なく継承していた ActivityInstrumentationTestCase2 から脱却します。

ActivityInstrumentationTestCase2 ベース

@RunWith(AndroidJUnit4.class)
public class MainActivityEspresso extends ActivityInstrumentationTestCase2<MainActivity> {

    private MainActivity activity;

    @Before
    @Override
    public void setUp() throws Exception{
        super.setUp();
        instrumentation = InstrumentationRegistry.getInstrumentation();     injectInstrumentation(instrumentation);
        activity = getActivity();
    }

    @Test
    public void example() {
        // describe test cases...
    }

    @After      
    @Override       
    public void tearDown() throws Exception {
        super.tearDown();
    }
}

ActivityTestRule ベース

@RunWith(AndroidJUnit4.class)
public class MainActivityEspresso {

    @Rule
    public ActivityTestRule<MainActivity> activityRule = new ActivityTestRule<>(MainActivity.class);

    @Before
    public void setUp(){
        activityRule.getActivity(); // Activityが欲しい場合、こう記述する
    }

    @Test
    public void example() {
        // describe test cases...
    }
}

大分すっきりしました。Activityの起動と破棄が ActivityTestRule に内包されているためです。タイミングはBefore/Afterのとき。
なお、公式のドキュメントを見ればわかるのですが、BeforeのタイミングでActivityを起動しない方法もとることが可能です。

ActivityTestRule(Class activityClass, boolean initialTouchMode, boolean launchActivity) のように宣言することも可能なので、以下のように@Testの中で意図したタイミングでActivityを起動することも可能。ただ、公式では必要最低限に抑えるように、としてますね。

@RunWith(AndroidJUnit4.class)
public class MainActivityEspresso {

    @Rule
    public ActivityTestRule<MainActivity> activityRule = new ActivityTestRule<>(MainActivity.class, true, false);

    @Test
    public void example() {
        activityRule.launchActivity(intent); // intentを与える
    }
}

from 2.1 to 2.2

  • espresso-web 2.2
    • EspressoがWebViewもサポートした!!
      • おそらく、APIドキュメントの android.support.test.espresso.web.~ というパッケージでまとめられているやつすべてがこれ
      • android.support.test.espresso.web.webdriverがあるので、多分dom取得なんかはAppiumと同じそう。
        • 話は少し逸れて、AppiumのDroidDriverとか
  • espresso-core 2.2
    • Dagger2、hamcrest v1.3の統合
      • Espresso内でのinjection、Dagger2ベースになったということかな。
  • espresso-contrib 2.2
    • Accessibility Checkの追加
      • Accessibilityの機能、例えば音声読み上げとかって機能テストする手段がcontentDesctiptionの有無調べるくらいしかなかったので、これは良い感じ
  • runner 0.3
    • JUnit 4.12 ベースへ移行 (from 4.10ベース)
    • hamcrest v1.3の統合
  • rule 0.3
    • DisableOnAndroidDebug の追加

基本的に全体的な不具合修正や少しづつな機能拡張なのですが、 contrib を導入したりするときにGradleの書き方でハマったのでメモ。

Gradleの書き方注意点

// espresso-coreがsupport-annotationsの22.2.0(2015年7月20日現在)を持っているので、以下のように強制的に新しいannotationsを使うか、com.android.supportではannotationsを除外する設定が必要です。
// Warning:Conflict with dependency 'com.android.support:support-annotations'. Resolved versions for app (22.2.1) and test app (22.2.0) differ.
configurations.all {
    resolutionStrategy.force 'com.android.support:support-annotations:22.2.1'
    // or
    // androidTestCompile.exclude group: 'com.android.support', module: 'support-annotations'
}

dependencies {
    androidTestCompile 'com.android.support.test:runner:0.3'
    androidTestCompile 'com.android.support.test:rules:0.3'
    // espresso-contrib が espresso-coreを含んでいるので、contribを入れるときはcoreは入れなくてOK
    // androidTestCompile('com.android.support.test.espresso:espresso-core:2.2')

    // contribはいくつかのcom,android.supportライブラリを内包しているので、以下のようにexcludeする必要があります。除かない場合、java.lang.NoClassDefFoundErrorのエラーがでます。
    // java.lang.NoClassDefFoundError: your.package.name
    androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2'){
        exclude group: 'com.android.support', module: 'support-v4'
        exclude group: 'com.android.support', module: 'recyclerview-v7'
    }
    androidTestCompile('com.android.support.test.espresso:espresso-web:2.2')

締め

AndroidのEspresso周り、適用範囲を広げてきましたね。iOSのXCUITestもそうなのですが、

(実行時間が短い) JUnit/XCTest < Espresso/XCUITest < uiautomator/UIAutomation (実行時間が長い)

という感じで、機能的なテストツールが拡充されてきた感じ。人海戦術からの脱却も加速しそうですね。イコール、EspressoやXCUITestを書く人は、実装箇所の理解もないと厳しそう。一方、Appiumなどはユーザシナリオと実装を切り離したテストを提供できるので、いままでと変わらず必要そう。結局は、何を目的として、どのような範囲で、何を防ぐかというテストのDesignの話にはなるのですが。

Android Test KitのEspressoなどのバージョンがあがってたのでざっと調べた」への1件のフィードバック

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中