Espressoを使ったUIテスト

2014-04-27T00:00:00+00:00 Android Java

公式: https://code.google.com/p/android-test-kit/wiki/Espresso

APIリファレンス: https://android-test-kit.googlecode.com/git-history/master/docs/javadocs/apidocs/index.html?r=master

タイトル通り、EspressoのUIテストキットなライブラリを使ってUIテストをするっていうのをやってみた。まぁ導入周りとかそっち系の単純な話だけなので(ry

アプリ構造

├── app
│   ├── build.gradle
│   ├── lib
│   │   └── espresso-1.1-bundled.jar
│   └── src
│       ├── androidTest
│       │   └── java
│       │       └── sample
│       │           └── test
│       │               └── espresso
│       │                   └── MainActivityTest.java
│       └── main
│           ├── AndroidManifest.xml
│           ├── assets
│           ├── java
│           │   └── sample
│           │       └── test
│           │           └── MainActivity.java
│           └── res (省略)
│
├── build.gradle
├── libraries
│   └── sample_library
│       ├── build.gradle
│       ├── sample_library.iml
│       └── src
│           └── main
│               ├── AndroidManifest.xml
│               ├── java
│               │   └── sample
│               │       └── test
│               │           └── library
│               │               └── SampleDialogFragment.java
│               └── res (省略)
└── settings.gradle

てな感じでDialogFragmentなSampleDialogFragmentを利用してダイアログを出してテキストを入力してOKするとToastが出るっていうだけ。んまぁEspressoを使ってテキスト入力させてクリックしても問題ないか的な所周りをテストしてみる

app/build.gradle

apply plugin: "android"

dependencies {
    compile project(":libraries:sample_library")
    compile "com.actionbarsherlock:actionbarsherlock:4.4.0@aar"
    androidTestCompile files("lib/espresso-1.1-bundled.jar")
}

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.3"

    defaultConfig {
        testInstrumentationRunner "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"
    }
}

特にJUnit周りなライブラリとか使ってないので依存性には入れてない。hamcrestに関してはespresso-1.1-bundled.jarに入ってるのでそれを使える(今回はそれも使ってない)

あとAndroidのgradleサポートにおいて0.9.xくらい辺りからinstrumentTestっていうのがandroidTestっていうのに変わった模様。

あとデフォルトのinstrumentationRunnerではなくandroid-test-kitなinstrumentationRunnerに変更しておく必要ありと

んまぁあとはテスト書くだけ

MainActivityTest.java

package sample.test.espresso;

import android.test.ActivityInstrumentationTestCase2;
import sample.test.MainActivity;
import sample.test.R;

import static com.google.android.apps.common.testing.ui.espresso.Espresso.onView;
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withId;
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.typeText;
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.closeSoftKeyboard;
import static com.google.android.apps.common.testing.ui.espresso.assertion.ViewAssertions.matches;
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withText;
import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.click;

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

    public MainActivityTest() {
        super(MainActivity.class);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();
        getActivity();
    }

    public void test() {
        onView(withId(R.id.dialog_text)).perform(typeText("hoge"));

        /* 実機等でテストする場合においてIMがデフォルトのAndroidキーボード
           ではないのを使っているような場合(Google IMEも同様)だとtypeText
           する際にあたっては一度スリープ等をした方が良い模様
        */
        // sleep(3000);

        /* ダイアログ等を出している場合においてはソフトウェアキーボードで
           隠れてしまって以降でのボタンが正常に取得できずにエラーになるので
           入力が終わったらcloseSoftKeyboardをしてソフトウェアキーボードを
           閉じる必要あり
        */
        onView(withId(R.id.dialog_text)).perform(closeSoftKeyboard());

        // わざとテストをfailさせる
        onView(withId(R.id.dialog_text)).check(matches(withText("fuga")));

        onView(withId(android.R.id.button1)).perform(click());

        /* 恐らくはpostDelayed等が行われる前にプロセスが終了する模様なので
           onClick等においてpostDelayedをしているようなケースな場合において
           は一度スリープを行なわないとそのままプロセスが終了してしまい
           postDelayedに及ぶ処理まで発生しない(かも)
        */
        sleep(5000);
    }

    public void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

大体なことはコメントで書いてるので(ry んまぁ公式読んだ方が単純に良いと思うので

テストを実行

gradle connectedAndroidTest

をやると動く。ちなみにこれも0.9.xくらい辺りからはconnectedInstrumentTestからconnectedAndroidTestに変わっているので

んまぁなんやかんやで動かすと

っていう感じ

追記

https://github.com/JakeWharton/double-espresso っていうのもある

gradle-android-test-plugin+robolectric+espresso angular.jsをやってみる (23) - ngTouchを使ってスワイプイベントを利用 -