最近尝试在项目中使用Espresso做UI测试,现在记下点笔记。
在android studio项目里打开应用build.gradle文件,在dependencies里添加依赖项:
// Warning:Conflict with dependency 'com.android.support:support-annotations'.
// Resolved versions for app (23.1.0) and test app (23.0.1) differ.
androidTestCompile 'com.android.support:support-annotations:23.1.0'
androidTestCompile 'com.android.support.test:runner:0.4'
// Set this dependency to use JUnit 4 rules
androidTestCompile 'com.android.support.test:rules:0.4'
// Set this dependency to build and run Espresso tests
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
// Set this dependency to build and run UI Automator tests
// androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
// RecycleViews Espresso supports
androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.1') {
exclude group: 'com.android.support', module: 'appcompat'
exclude group: 'com.android.support', module: 'support-v4'
exclude module: 'recyclerview-v7'
}
在android defaultConfig里添加这段配置:
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
到这里,配置已经成功!
在项目test路径下,创建测试类MainActivityTest.class
一般用到的测试库和方法有:
import static android.os.SystemClock.sleep;
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.pressBack;
import static android.support.test.espresso.action.ViewActions.typeText;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;//这是个很好东西
这里偶尔会出现使用方法的时候没有建议添加import,所以先给上面的import了
在测试类里添加以下代码:
@RunWith(AndroidJUnit4.class)
@LargeTest
public class CaseBookMarkCheck {
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class);
public MainActivity mMainActivity = null;
@Before
public void setMainActivity() {
this.mMainActivity = mActivityRule.getActivity();
}
@Test
public void testMain() {
// 最好添加延迟,不然速度会很快,连UI界面都看不到
// 有时做网络请求的时候也要使用到
sleep(5000);
// 通过Id获取控件,也可以通过withText获取
onView(allOf(withId(R.id.btnStart), isDisplayed())).perform(click());
sleep(3000);
}
}
运行时,需要在运行的config上把Specific instrumentation runner(optional)修改为:
android.support.test.runner.AndroidJUnitRunner
因为刚刚接触这好东西,对里面的API并没有太熟悉,于是写了一个比较容易理解的方法去获取当前控件:
/**
* 通过matcher的规则,获取指定当前UI的控件对象
* DENO:
* RecyclerView recyclerView =
* UITestUtil.getControl(allOf(withId(R.id.view), isDisplayed()), RecyclerView.class);
* @param matcher matcher的规则
* @param type UI控件的class
* @param <T> 转换的UI控件
* @return 返回UI控件
*/
public static <T extends View> T getControl(final Matcher<View> matcher, final Class<T> type){
T targetUIObject;
final View[] target = new View[1];
onView(matcher).perform(new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isAssignableFrom(type);
}
@Override
public String getDescription() {
return "getting " + type.getSimpleName();
}
@Override
public void perform(UiController uiController, View view) {
target[0] = view;
}
});
targetUIObject = (T) target[0];
return targetUIObject;
}
// 使用方式,recyclerView滑动到最后一项
RecyclerView recyclerView = getControl(allOf(withId(R.id.recyclerView), isDisplayed()), RecyclerView.class);
recyclerView.smoothScrollToPosition(recyclerView.getAdapter().getItemCount() - 1);
参考:
https://google.github.io/android-testing-support-library/samples/index.html
https://google.github.io/android-testing-support-library/docs/espresso/setup/