1. 程式人生 > >Android自動化測試框架Espresso(二)——測試Toast彈出內容

Android自動化測試框架Espresso(二)——測試Toast彈出內容

Android中的Toast是我們經常會使用的,能夠方便的在介面上彈出一個提示語句,還可以控制顯示的時長,十分方便。使用Espresso測試Toast的彈出內容不是很好操作,主要由於Toast的佈局並不是屬於我們當前應用的,而是通過另一個Sevice控制的,這個原理可以看看相關的一些博文,我這裡不再詳細說明。當時為了測試Toast是否顯示正確,也是查了不少文章,最後在Stack Overflow找到了解決的辦法,這裡給大家介紹一下,但是並不是很完美,後面會詳細說明。

我們採用TDD的模式做我們的簡單Demo,我們希望介面上有一個文字為點選的按鈕,點選該按鈕,會彈出一個文字為clicked的Toast,按照這個說明,編寫我們的測試程式碼(專案的Gradle配置見上一篇文章)

package com.yjp.toasttest;

import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.widget.Button;

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.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.not;

@RunWith(AndroidJUnit4.class)
public class MainActivityTest {

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

    @Test
    public void testClickButtonToast() throws Exception {

        //介面上有一個文字為點選的按鈕並點選按鈕
        onView(allOf(withText(R.string.click), instanceOf(Button.class)))
                .check(matches(isDisplayed()))
                .perform(click());

        //會彈出一個文字為clicked的Toast
        Thread.sleep(1000);
        onView(withText(R.string.clicked_en))
                .inRoot(withDecorView(not(mActivityRule.getActivity().getWindow().getDecorView())))
                .check(matches(isDisplayed()));
    }
}

首先,我們使用withText和instanceOf兩個View Matcher選擇出了我們的Button,檢查該Button是否顯示,執行了click()操作(View Action)。然後我們sleep了1s,這個就是我上面提到的不太完美的地方,如果不加延時,可能Toast會檢測不到。休眠1s後,找到Toast的佈局,這裡通過withText找到對應的Toast的檢視,但這無法保證就是Toast,也有可能在我們的介面中會有其他的控制元件使用了clicked這個文字,所以,我們還需要保證我們找的Toast檢視不在主介面的DecorView中,這裡使用了withDecorView和not兩個Matcher。最後,通過check檢查是否顯示。

上面的程式碼中,我們將點選和clicked兩個文字定義為了兩個字串資源,可以看到withText可以直接傳遞字串資源。

<string name="click">點選</string>
<string name="clicked_en">clicked</string>

現在執行測試,會報錯,錯誤不貼了,意思就是找不到滿足條件的按鈕,畢竟我們的MainActivity還沒有完成。我們完成我們的佈局,新增一個按鈕,文字為點選(R.string.click)。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="com.yjp.toasttest.MainActivity">

    <Button
        android:id="@+id/click_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/click"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.501" />

</android.support.constraint.ConstraintLayout>

佈局我只是基於專案自動生成的,修改TextView為Button,text設定為點選,我們再次執行測試,這次報錯變了,告訴我們找不到Toast的佈局。我們新增程式碼
package com.yjp.toasttest;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button clickButton = (Button) findViewById(R.id.click_button);
        clickButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String toast = getString(R.string.clicked_en);
                Toast.makeText(MainActivity.this, toast, Toast.LENGTH_SHORT).show();
            }
        });
    }
}

再次執行測試,這次測試通過,說明為我們的程式碼已經滿足了需求的要求。