Android StudioでEspressoを使ったUIテストのやり方

#はじめに
**Espresso**はAndroid StudioのUIテスト(画面のテスト)が出来ます。その使い方を紹介します。
#今回は・・・
以下のようなアプリケーションがあるとします。

```java:MainActivity.java
package com.websarva.wings.android.uitest1;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private TextView textView;
    private EditText editText;
    private String text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView=findViewById(R.id.text);
        editText=findViewById(R.id.editTextTextPersonName);
    }

    //ボタンを押すと挨拶を表示
    public void display(View view){
        text=editText.getText().toString();
        textView.setText(text+"さん、こんにちは！");

    }


}
```

```xml:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/editTextTextPersonName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="216dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:hint="名前を入力"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="268dp"
        android:onClick="display"
        android:text="表示"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
```
画面はこんな感じ
![Screenshot_20211223-030245.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1925070/146fae26-4e85-2ecc-2e16-5ae7ad245306.png)

名前を入力して「表示」を押すと、挨拶が表示される。
![Screenshot_20211223-030313.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1925070/e438e429-8c54-18da-9bfe-44c8dda6cc5c.png)
このアプリケーションのUIテストをします。
#手順
**build.gradleに以下を追加**

```gradle
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test:rules:1.1.0'
```
**androidTestにテストクラスを作る**
下の画像のように**パッケージ名(andoidTest)**と書かれているフォルダがあります。すでにExampleInstrumentedTest.javaがありますね。ここにクラスを作ります。
![スクリーンショット 2021-12-23 135527.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1925070/3f7783e5-b0f7-a74b-57be-9324fbed95ac.png)
いつも通り、フォルダの上で右クリック→New→Java Class。名前はEsTestにしときます。![スクリーンショット 2021-12-23 140333.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1925070/54b69728-1f9a-3e00-0b53-cf1b58b30e31.png)

**どんなUIテストでも必要なコード**
ではこのEsTest.javaに以下を書きましょう。

```java:EsTest.java
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AndroidJUnit4.class)
@LargeTest
public class EsTest {
    private String stringToBetyped;

    @Rule
    public ActivityTestRule<MainActivity> activityRule =
            new ActivityTestRule<>(MainActivity.class);

    @Before
    public void initial(){
        //事前処理
    }

    @Test
    public void listGoesOverTheFold() {
        //テスト内容
    }
}
```
上がUIテストコードの雛形です。「事前処理」と「テスト内容」のところを穴埋めします。
穴埋めした結果が以下です。


```java:EsTest.java
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;

import static androidx.test.espresso.Espresso.onView;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AndroidJUnit4.class)
@LargeTest
public class EsTest {
    private String stringToBetyped;

    @Rule
    public ActivityTestRule<MainActivity> activityRule =
            new ActivityTestRule<>(MainActivity.class);

    @Before
    public void initial(){
        stringToBetyped="たなか";
    }

    @Test
    public void listGoesOverTheFold() {
        onView(withId(R.id.editTextTextPersonName)).perform(replaceText(stringToBetyped));
        onView(withId(R.id.button)).perform(click()); 
        onView(withId(R.id.text)).check(matches(isDisplayed()));
    }
}
```
穴埋めしたコードの説明をします。
**initial**では、初期化で後のテストで使いたい変数を定義します。

```java
  @Before
    public void initial(){
        stringToBetyped="たなか";
    }
```
**listGoesOverTheFold()**ではUIテストを行います。基本は下の形です。

```java
onView(withId(目標の部品のid)).perform(やりたいこと);
onView(withId(目標の部品のid)).check(チェックしたいこと);
```
例えばコードにある

```java
onView(withId(R.id.editTextTextPersonName)).perform(replaceText(stringToBetyped));
```
は

```java
onView(withId(名前の欄を)).perform("たなか"のテキストにする);
```
ということです。

```java
onView(withId(R.id.button)).perform(click());
```
は

```java
onView(ボタンを).perform(クリックする);
```
ですし、

```java
onView(withId(R.id.text)).check(matches(isDisplayed()));
```
は

```java
onView(挨拶のテキストが).check(表示されているか);
```
になります。つまり
**名前の欄に"たなか"と入力してボタンを押したら、挨拶のテキストが表示されるのか**をテストするコードです。

**いざ、テスト！**
EsTest.javaのファイルの上で右クリック→Runしてください。すると、下のようにテストを通過出来たことが分かります
![スクリーンショット 2021-12-25 110320.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1925070/8fc6a464-0de8-4399-05c7-c6e60193e415.png)

もし、

```java
   public void display(View view){
        text=editText.getText().toString();
        //textView.setText(text+"さん、こんにちは！");
    }
```
このようにテキストが表示されないコードを書いてテストすると
![スクリーンショット 2021-12-25 110358.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1925070/08519686-6a89-5f70-f130-20a55e4cfa96.png)
テストが通過出来なかったことが分かります。

#終わりに
少しでも参考になれば幸いです！