LoginSignup
43
47

More than 5 years have passed since last update.

EspressoでAndroidのUIテストコード

Last updated at Posted at 2016-01-22

Espressoとは

  • googleが開発を行っている。
  • AndroidのUIテストフレームワーク
  • 自動同期(Automatic Synchronization)
  • 基本的な操作が簡単にかける(テキスト入力、クリック、スクロール、スワイプ)
  • 自分が欲しいアクションが提供されていない場合は自分で作ることも可能

導入

gradleに以下のコードを追加
最新のバージョンは公式サイトを参照してください。

dependencies {
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
}

新規登録画面のフローテスト

idとパスワードを入力し、ボタンを押すと次の画面へ遷移するアプリを考えます。
この時、登録に失敗した場合には上の方にエラーメッセージを表示します。

image image image

SignUp失敗時のテスト

@Test
public void checkErrorMessage() {
    onView(withId(R.id.user_id)).perform(replaceText(""));
    onView(withId(R.id.password)).perform(replaceText(password), closeSoftKeyboard());
    onView(withId(R.id.signup_button)).perform(click());
    onView(withId(R.id.error_message)).check(matches(withText("ユーザーIDを入力してください。")));
}

SignUp成功時のテスト

@Test
public void checkSignUp() {
    onView(withId(R.id.user_id)).perform(replaceText(userId));
    onView(withId(R.id.password)).perform(replaceText(password), closeSoftKeyboard());
    onView(withId(R.id.signup_button)).perform(click());
    onView(withId(R.id.hello_world)).check(matches(withText("Hello World, " + userId + "!!")));
}

CustomMatcher

先ほどの上のwithTextでは画面上のテキストの値をチェックしていましたが、自分でカスタマイズしたMatcherも作ることができます。
例えばTextViewの色をチェックするCustomMatcherを実装するにはmatchesSafelyメソッドとdescribeToメソッドをオーバーライドします。
matchesSafelyで独自のMatcherを定義し、describeToでログの表示を定義します。

private static Matcher<Object> withColor(final Matcher<Integer> integerMatcher) {
    return new BoundedMatcher<Object, TextView>(TextView.class) {
        @Override
        public boolean matchesSafely(TextView textView) {
            return integerMatcher.matches(textView.getCurrentTextColor());
        }

        @Override
        public void describeTo(Description description) {
            description.appendText("with resource color : ");
            integerMatcher.describeTo(description);
        }
    };
}
onView(withId(R.id.error_message))
        .check(matches(withColor(is(ContextCompat.getColor(activity, android.R.color.holo_red_light)))));

Idling Resource

ある条件を満たした後にアクションを行う。
アニメーションが終了した後にスクロールを開始する。5秒たった後にボタンを押下する。など。
これは、IdlingResourceをimplementsしたクラスで実装します。
以下はhoge秒後にアクションを行う処理を行う場合

public class ElapsedTimeIdlingResource implements IdlingResource {
    private final long startTime;
    private final long waitingTime;
    private IdlingResource.ResourceCallback resourceCallback;

    public ElapsedTimeIdlingResource(long waitingTime) {
        this.startTime = System.currentTimeMillis();
        this.waitingTime = waitingTime;
    }

    @Override
    public String getName() {
        return ElapsedTimeIdlingResource.class.getName() + ":" + waitingTime;
    }

    @Override
    public boolean isIdleNow() {
        long elapsed = System.currentTimeMillis() - startTime;
        boolean idle = (elapsed >= waitingTime);
        if (idle) {
            resourceCallback.onTransitionToIdle();
        }
        return idle;
    }

    @Override
    public void registerIdleTransitionCallback(IdlingResource.ResourceCallback resourceCallback) {
        this.resourceCallback = resourceCallback;
    }
}

@Test
public void checkErrorMessage() {
    // Now we wait 8 seconds for some reason
    IdlingResource idlingResource = new ElapsedTimeIdlingResource(DateUtils.SECOND_IN_MILLIS * 8);
    Espresso.registerIdlingResources(idlingResource);

    onView(withId(R.id.error_message)).check(matches(withColor(is(ContextCompat.getColor(activity, android.R.color.holo_red_light)))));

    // Clean up
    Espresso.unregisterIdlingResources(idlingResource);
}

考察

Espressoの文法は見た目がわかりやすく、コード量も少なくて済むのですごく良いです。
この記事のコードはGitHub上にEspressoDemoという名前で公開しているので、ぜひ。

話は逸れますが、個人的にAndroidアプリMapMeとNetflixの映画レビューサイトWhatchaSeeを運営しています。
拝見していただけるとありがたいです。

43
47
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
47