Android UI 测试框架Espresso详解
1. Espresso测试框架
Espresso是Android的测试框架,可简化编写可靠的用户界面测试的过程。
Google于2013年10月发布了Espresso框架。自其2.0版本以来,Espresso已成为Android支持存储库的一部分。
Espresso会自动将您的测试操作与应用程序的用户界面同步。该框架还确保您的Activity在测试运行之前就已经开始。它还让测试等到所有观察到的后台Activity都完成为止。
它旨在测试单个应用程序,但也可以用于跨应用程序进行测试。如果用于在应用程序外部进行测试,则只能执行黑盒测试,因为您无法访问应用程序外部的类。
Espresso基本上具有三个组成部分:
-
ViewMatchers-允许在当前视图层次结构中查找视图
-
ViewActions-允许对视图执行操作
-
ViewAssertions-允许声明视图状态
Espresso测试的案例构造如下:
Espresso测试
onView(ViewMatcher)
.perform(ViewAction)
.check(ViewAssertion);
onView |
-查找视图 |
perform |
-对视图执行操作 |
check |
-验证断言 |
以下代码演示了Espresso测试框架的用法。
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.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
// image more code here...
// test statement
onView(withId(R.id.my_view)) // withId(R.id.my_view) is a ViewMatcher
.perform(click()) // click() is a ViewAction
.check(matches(isDisplayed())); // matches(isDisplayed()) is a ViewAssertion
// new test
onView(withId(R.id.greet_button))
.perform(click())
.check(matches(not(isEnabled()));
如果Espresso无法通过找到一个视图ViewMatcher,则它将整个视图层次结构包含在错误消息中。这对于分析问题很有用。
2.提供Intents Espresso
2.1.安装
使用Android SDK管理器安装Android支持存储库。
2.2.为Espresso配置Gradle构建文件
要使用Espresso进行测试,请将以下依赖项添加到应用程序的Gradle构建文件中。
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
// Android runner and rules support
androidtestImplementation 'com.android.support.test:runner:0.5'
androidtestImplementation 'com.android.support.test:rules:0.5'
// Espresso support
androidtestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
// add this for intent mocking support
androidtestImplementation 'com.android.support.test.espresso:espresso-intents:2.2.2'
// add this for webview testing support
androidtestImplementation 'com.android.support.test.espresso:espresso-web:2.2.2'
}
确保在您的应用的构建文件中将android.support.test.runner.AndroidJUnitRunner指定为testInstrumentationRunner参数值。通过,packagingOptions您可能必须排除LICENSE.txt,具体取决于您所使用的库。以下清单是一个示例。
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion '22.0.1'
defaultConfig {
applicationId "com.example.android.testing.espresso.BasicSample"
minSdkVersion 10
targetSdkVersion 22
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
packagingOptions {
exclude 'LICENSE.txt'
}
lintOptions {
abortOnError false
}
}
dependencies {
// as before.......
}
2.3.设备设置
建议在用于测试的Android设备上打开动画。动画可能会使Espressos检查资源浪费。
3.练习:第一次Espresso测试
3.1.创建被测项目
创建一个名为Espresso First的新Android项目,包名称为com.vogella.android.espressofirst。使用空白模板作为该项目的基础。
将生成的activity_main.xml布局文件更改为以下内容。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<EditText
android:id="@+id/inputField"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/changeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button" android:onClick="onClick"/>
<Button
android:id="@+id/switchActivity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change Text" android:onClick="onClick"/>
</LinearLayout>
创建一个名为activity_second.xml的新文件。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="@+id/resultView" />
</LinearLayout>
使用以下代码创建一个Activity。
package com.vogella.android.espressofirst;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class SecondActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
TextView viewById = (TextView) findViewById(R.id.resultView);
Bundle inputData = getIntent().getExtras();
String input = inputData.getString("input");
viewById.setText(input);
}
}
同时调整MainActivity。
package com.vogella.android.espressofirst;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends Activity {
EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.inputField);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.changeText:
editText.setText("Lalala");
break;
case R.id.switchActivity:
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("input", editText.getText().toString());
startActivity(intent);
break;
}
}
}
3.2.调整应用程式build.gradle
按照Espresso的Gradle构建文件的配置中所述执行设置。
3.3.创建您的Espresso测试
package com.vogella.android.espressofirst;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
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.action.ViewActions.closeSoftKeyboard;
import static android.support.test.espresso.action.ViewActions.typeText;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
@RunWith(AndroidJUnit4.class)
public class MainActivityEspressoTest {
@Rule
public ActivityTestRule<MainActivity> mActivityRule =
new ActivityT