【Android】Espressoを一杯(和歌山トイレマップで遊んでみる 9)
はじめに
- 和歌山トイレマップで遊んでみる 1
- 和歌山トイレマップで遊んでみる 2
- 和歌山トイレマップで遊んでみる 3
- 和歌山トイレマップで遊んでみる 4
- 和歌山トイレマップで遊んでみる 5
- 和歌山トイレマップで遊んでみる 6
- 和歌山トイレマップで遊んでみる 7
- 和歌山トイレマップで遊んでみる 8
今回はUIテストツールである、Espressoを使ってみた時のあれこれをまとめます。
インストール
まずはインストールから。EspressoはJUnit4を使用するため、build.gradleに追加します。
build.gradle
~省略~ android { compileSdkVersion 23 buildToolsVersion "23.0.2" defaultConfig { applicationId "jp.searchwakayamatoilet" minSdkVersion 16 targetSdkVersion 23 versionCode 2 versionName "1.1" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } ~省略~ } ~省略~ dependencies { ~省略~ // App's dependencies, including test androidTestCompile 'com.android.support:support-annotations:23.2.0' androidTestCompile 'com.android.support.test:runner:0.4.1' androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1' ~省略~ }
- 特にdependenciesの記述は結構バージョンごとに違っているようで、見るサンプルごとに異なっていたりもしますが、私の2016.03.08現在の環境では上記の記述以外ではエラーとなるようでした。
テストケースを書く
MainActivityTest.java
~省略~ import android.support.test.InstrumentationRegistry; import android.support.test.espresso.action.ViewActions; import android.support.test.espresso.matcher.ViewMatchers; import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.LargeTest; import android.widget.EditText; import static android.support.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.withText; @RunWith(AndroidJUnit4.class) @LargeTest public class MainActivityViewTest { @Rule public ActivityTestRulemainActivityRule = new ActivityTestRule(MainActivity.class); @Before public void setUp() throws Exception { // テスト対象ページへの遷移など、テスト前に実行する処理を書く. } @Test public void hasToolbar() throws Exception{ // Toolbarが表示されているかをチェックする. onView(ViewMatchers.withId(R.id.toolbar)).check(matches(isDisplayed())); } ~省略~ @Test public void hasEditTextOnSearchView() throws Exception{ // SearchViewをクリックする. onView(ViewMatchers.withId(R.id.searchview)).perform(ViewActions.click()); // SearchViewの入力欄に「test」と入力してSubmitボタンを押す. onView(ViewMatchers.isAssignableFrom(EditText.class)).perform(ViewActions.typeText("test"), ViewActions.pressKey(66)); } @Test public void isSuggestSearchAllShown() throws Exception{ onView(ViewMatchers.withId(R.id.searchview)).perform(ViewActions.click()); // SearchViewの入力欄に「" "」と入力したあと、「""」に置き換える. onView(ViewMatchers.isAssignableFrom(EditText.class)).perform(ViewActions.typeText(" "), ViewActions.replaceText("")); // 全件検索用のサジェストが表示されることを確認する. onView(ViewMatchers.withId(R.id.suggest_list)).check(matches(isDisplayed())); } @Test public void hasAboutAppButtonInMenu() throws Exception { // ToolbarのMenuを表示する. openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext()); // ToolbarのMenuにある「about」ボタンを押す. onView(ViewMatchers.withText(R.string.action_about)).perform(ViewActions.click()); } @Test public void isAboutFragmentShown() throws Exception { // 同じ処理なら別メソッドを呼び出してその後の処理だけを記述することもできる. this.hasAboutAppButtonInMenu(); onView(ViewMatchers.withId(R.id.about_fragment)).check(matches(isDisplayed())); } ~省略~ @Test public void hasCreaditsRetrolambdaViewOnAboutAppFragment() throws Exception{ this.hasAboutAppButtonInMenu(); // Menuからaboutページを開き、TextViewをスクロール. onView(ViewMatchers.withText(R.string.about_credits_retrolambda)).perform(ViewActions.scrollTo(), ViewActions.click()); onView(ViewMatchers.withId(R.id.about_credits_title_retrolambda)).check(matches(isDisplayed())); onView(ViewMatchers.withId(R.id.about_credits_retrolambda)).check(matches(isDisplayed())); onView(ViewMatchers.withId(R.id.about_credits_retrolambda_link)).check(matches(isDisplayed())); } ~省略~
- JUnit4を使用するため、@RunWith(AndroidJUnit4.class)をクラスに付与します。
- 各テストケースには@Testを付与します。
- 各テストケースの実行順は保証されません。
- 「matches(isDisplayed())」は画面上に見えている範囲のみチェックするため、ソース上画面内にあったとしても隠れている状態ならテストに失敗します。
終わりに
今回はUIのテストのみを行いました。Mockitoを使った内部処理のテストも取り入れていきたいところです。
参考
- Espresso setup instructions - Android Testing Support Library
- testing - Warning:Conflict with dependency 'com.android.support:support-annotations' - Stack Overflow
- 【Android】Espressoを使ってUIをテストする - Qiita
- Android Espresso typeText into EditText in ActionBar - Stack Overflow
- android-testing - GitHub
- java - How to scroll down the screen in the android espresso test? I need to validate the text present on the screen - Stack Overflow