什么是Espresso?
Espresso是google提供的为Android app UI测试框架,在2013年google就发布了Espresso,在Espresso2.0版本的时候就集成在sdk中。
集成到项目中
首先你要确保你sdk中安装Android support Repository
(https://img-blog.csdn.net/20160414092543731)
之后我们新建一个项目(靠,废话。没项目我们玩毛线~)
下面这一步非常重要,**一定要注意,一定要注意,一定要注意(重要的事情说3遍)**
在你的build.gralde中填上依赖
dependencies {
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2'
}
同时在defaultConfig中加上
defaultConfig {
......
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
下面就是我自己新建的一个模板build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.example.administrator.testdemo02"
minSdkVersion 15
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.3.0'
androidTestCompile 'com.android.support:support-annotations:23.3.0'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2'
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
小tips
1.我在这一步的时候出了一个问题 IDE 给我报了一个错误
Error:Conflict with dependency 'com.android.support:support-annotations'. Resolved versions for app (23.3.0) and test app (23.1.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details.
后来找到问题原因是’com.android.support:support-annotations’包的版本androidTest和 正常项目不统一,找到原因就好办了 那我们在依赖这加一个androidTestCompile ‘com.android.support:support-annotations:23.3.0’ 不就可以了。
重新rebuild 没报错误就是成功了。
2.我在这里又发现了一个新的认知,就是 依赖的作用域是有区别的。 (https://img-blog.csdn.net/20160413154706106)
这个是正常的一个项目结构 ,大家可以发现在app/src下面有3个文件夹,我们在依赖处的androidTestCompile ,testCompile ,分别对应的是AndoridTest 和Test文件夹,compile 是全局的依赖,3个文件夹下都可以使用,有兴趣的同学可以试下 用androidTestCompile 依赖个第三方 在主项目中可不可以找到这个依赖包。
Espresso语法
其实UI 自动化测试最根本是把自己当成用户,用户关心什么?用户只关心显示的信息,信息从哪来,怎么来的,用户其实不关心。所以思路就是
找到元素 给这个元素一些操作 检测结果和我们的一不一致
Espresso语法也是如此
找到元素
Espresso提供了一个找元素的方法onView()来寻找UI上的元素,方法定义如下
public static ViewInteraction onView(final Matcher<View> viewMatcher) {}
onView的参数是一个Matcher对象,这里Espresso 提供了几种方式找到UI
withText("SOMETEXT") 用UI里面的Test判断
withId() 用UI中Id判断
allOf(,) 这个有点特殊,onview方法必须保证UI的唯一性,如果前两种方式并不能找到唯一的一个UI,那么系统会报出一个AmbiguousViewMatcherException 异常。 这种情况下我们就必须使用第三种方式,来确保只能找到1个UI 例:onView(allOf(withId(id), withText(text)))
但是如果单一的寻找可以判断出是唯一的UI 我们不建议使用allOf的语法
操作元素
我们在找元素的方法上 是有返回值的,返回一个ViewInteraction 对象,这个对象可以直接调用perform()方法来操作UI
例 onView().perform(click(),typeText("Hello"),closeSoftKeyboard()) 这个方法的参数是一个可变数组,我们可以在参数中加许多行为 这个例子就是点击,将Hello赋值到控件上,关闭键盘。
其实这里面可以添好多行为 感兴趣的同学可以直接去android.support.test.espresso.action.ViewActions里面看方法
检查结果
最后一步就是检查结果了,方法是oncheck() 里面参数是和我们查找UI的参数是一致的!所以我们可以这么写
onView(withId(R.id.inputField)).check(matches(withText("Lalala")));
更多的Matcher对象的写法可以参照Mather详解
第一个Espresso项目
说到测试,我们肯定会要有一个项目,所以建一个简单的2个Activity
MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.changeText:
EditText editText = (EditText) findViewById(R.id.inputField);
editText.setText("Lalala");
break;
case R.id.switchActivity:
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("input","NewText");
startActivity(intent);
break;
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
SecondActivity
public class SecondActivity extends AppCompatActivity {
@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);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
activity_second
<?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>
准备工作做好后 我们就可以写test类了 在AndroidTest包下面建一个MainActivityEspressoTest类
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 这句代表了运行的是哪个Activity
@Rule
public ActivityTestRule<MainActivity> mActivityRule =
new ActivityTestRule<>(MainActivity.class)
// Test 注解代表了我们要运行的测试方法 方法会从上到下依次运行
@Test
public void ensureTextChangesWork() {
// // Type text and then press the button.
onView(withId(R.id.inputField))
.perform(typeText("HELLO"), closeSoftKeyboard())
onView(withId(R.id.changeText)).perform(click())
//
// // Check that the text was changed.
onView(withId(R.id.inputField)).check(matches(withText("Lalala")))
}
@Test
public void changeText_newActivity() {
// Type text and then press the button.
onView(withId(R.id.inputField)).perform(typeText("NewText"),
closeSoftKeyboard())
onView(withId(R.id.switchActivity)).perform(click())
// 这里可以发现Test只是找UI
onView(withId(R.id.resultView)).check(matches(withText("NewText")))
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
写完之后我们在项目中运行这个Test就可以看结果啦~~
(https://img-blog.csdn.net/20160413164441483)
ok 这次的分享到此就结束了,如果有机会的话,会再之后更新更多的Espresso用法 ~~拜了个拜