44
48

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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を運営しています。
拝見していただけるとありがたいです。

44
48
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
44
48

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?