読者です 読者をやめる 読者になる 読者になる

うさがにっき

読書感想文とプログラムのこと書いてきます

Espressoを使った自動化テスト環境を作成する

Android Espresso

概要

Espressoがsupportライブラリに取り込まれたことにより、GUIのテストがしやすくなったと聞いたので試してみることに
まずはHello World!がテストできるところを目標に

詳細

端末設定

テストが不安定にならないようにシステム側のアニメーションを無効にしておく
設定 -> 開発者向けオプションの以下の3つ

  • ウィンドウアニメスケール
  • トランジションアニメーションスケール
  • Animator 再生時間スケール

SDKの設定

EspressoはSDKマネージャからAndroid support Repositoryをインストールすることで使用可能になる

gradleの設定

android-testing/build.gradle at master · googlesamples/android-testing · GitHub
の真似して以下の感じに

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig {
        applicationId "test.co.jp.espressotest"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.0.1'

    androidTestCompile 'com.android.support:support-annotations:23.0.1'
    androidTestCompile 'com.android.support.test:runner:0.4.1'
    androidTestCompile 'com.android.support.test:rules:0.4.1'
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
}

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"を指定することでjunit4が使えるように
androidTestCompile~系を追加することによりテストに使うアノテーションやクラスが使えるように

テストコードを書く

src/androidTest/java/パッケージ名下にテストクラスを作る、特に何も継承する必要はなし

import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;

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 HelloWorldEspressoTest {

    // テスト実行前に行われるメソッド
    @Rule
    public ActivityTestRule<MainActivity> mActivityRule
            = new ActivityTestRule(MainActivity.class);

    @Test
    public void listGoesOverTheFold() {
        onView(withText("Hello World!")).check(matches(isDisplayed()));
    }
}

ポイントをいくつか

  • @LargeTestなどわけることにより、コマンドラインからテストを叩いた際、実行する大きさのテストが選べる
  • @Ruleはテスト実行前に実行されるメソッド、ActivityTestRuleはUIスレッド上でテストが行えるクラス、テスト前にテスト対象となるActivityを指定して実行する
  • onViewやwithText, matchesなどはテスト中よく使うメソッドなのでstaticインポートしておくと良い

テスト実行

Run -> Edit Configrations -> default -> Android Testsからテストのデフォルトを変更する
以下の感じにする
f:id:tiro105:20151010213755p:plain

テストクラスを選びテスト実行
こんな感じに結果が出る

…

Running tests
Test running startedFinish

ちなみに失敗するとこんな感じ

android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with text: is "Hello world!"

View Hierarchy:
+>DecorView{id=-1, visibility=VISIBLE, width=1080, height=1920, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=3}
|
+->LinearLayout{id=-1, visibility=VISIBLE, width=1080, height=1776, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
|
...

条件にあったViewが見つからなかったと教えてくれる