定义
一个基于instrumentation-based API 的UI测试框架,运行于AndroidJunitRunner中。
特点
- One of the key parts of Espresso is its ability to synchronize all test actions. Espresso waits until the UI is idle before it moves to the next operation.
From https://codelabs.developers.google.com/codelabs/android-testing/index.html?index=..%2F..%2Findex#9
- Espresso detects when the main thread is idle, so it is able to run your test commands at the appropriate time, improving the reliability of your tests. This capability also relieves you from having to add any timing workarounds, such as Thread.sleep() in your test code.
- 一次只能测试一个应用程序。
概括
OnView() => Click()==>Check():
1.onView 、Ondata找到一个view。
2.ViewAction.click()等执行一组UI交互操作。
3.等待UI交互操作执行完毕,使用ViewAssertions去断言期望的状态或行为。
就像下面代码片段:
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
找到一个View
Calling methods in the ViewMatchers class. For example, to find a view by looking for a text string it displays, you can call a method like this:
onView(withText("Sign-in"));
Similarly you can call withId() and providing the resource ID (R.id) of the view, as shown in the following example:
onView(withId(R.id.button_signin));
Android resource IDs are not guaranteed to be unique. If your test attempts to match to a resource ID used by more than one view, Espresso throws an AmbiguousViewMatcherException.
From https://developer.android.com/training/testing/ui-testing/espresso-testing.html#build
更加精确地找到一个view:
onView(allOf(withId(R.id.button_signin), withText("Sign-in")));
From https://developer.android.com/training/testing/ui-testing/espresso-testing.html#build
注意
如果是AdapterView类型的viewGroup中的某个子View,(ListView、GridView)则需要使用onData()。
执行交互操作
用来执行UI交互操作的API封装在ViewActions中,如:
• ViewActions.click(): Clicks on the view.
• ViewActions.typeText(): Clicks on a view and enters a specified string.
• ViewActions.scrollTo(): Scrolls to the view. The target view must be subclassed from ScrollView and the value of its android:visibilityproperty must be VISIBLE. For views that extend AdapterView (for example, ListView), the onData() method takes care of scrolling for you.
• ViewActions.pressKey(): Performs a key press using a specified keycode.
• ViewActions.clearText(): Clears the text in the target view.
From https://developer.android.com/training/testing/ui-testing/espresso-testing.html#build
验证结果
ViewInteraction 、 DataInteraction提供了check()去验证UI的状态是否符合期望。Check()接受一个参数ViewAssertion .
// Check that the text was changed.
onView(withId(R.id.textToBeChanged))
.check(matches(withText(STRING_TO_BE_TYPED)));
From https://developer.android.com/training/testing/ui-testing/espresso-testing.html#build
Idling resources
Espresso关键的优点是: 自动等待UI变成闲置状态才开始执行下一步操作。例如,Espresso会自动等待AsyncTask后台操作执行完毕才开始执行下一步操作。 不需要自己去执行wait()或者sleep()。
但是,如果自己管理线程调度后者其他后台服务时,也会遇到不能同步的情况。不过Espresso提供了Idling resources去处理同步。
From https://codelabs.developers.google.com/codelabs/android-testing/index.html?index=..%2F..%2Findex#9
我们可以使用Espresso内置的实现类
CountingIdlingResource
在Test中,需要在@Before函数里注册registerIdlingResource.
它包含一个计数器,可调用increment()decrement()访问它。
// The network request might be handled in a different thread so make sure Espresso knows
// that the app is busy until the response is handled.
EspressoIdlingResource.increment(); // App is busy until further notice
mNotesRepository.getNotes(new NotesRepository.LoadNotesCallback() {
@Override
public void onNotesLoaded(List<Note> notes) {
EspressoIdlingResource.decrement(); // Set app as idle.
mNotesView.setProgressIndicator(false);
if (notes.isEmpty()) {
mNotesView.showNotesEmptyPlaceholder();
} else {
mNotesView.showNotes(notes);
}
}
});
当执行耗时操作时,可调用
EspressoIdlingResource.increment()//UI开始处于忙碌状态
在耗时操作完成时,在回调函数调用
EspressoIdlingResource.decrement(); // 通知Espresso此时UI处于闲置状态,
这时候可继续执行下一步操作。
相关链接
- https://github.com/googlesamples/android-testing
- https://stackoverflow.com/questions/31076228/android-testing-uiautomator-vs-espresso/34261832#34261832
- https://codelabs.developers.google.com/codelabs/android-testing/index.html?index=..%2F..%2Findex#0
- https://objectpartners.com/2013/09/18/the-benefits-of-using-assertthat-over-other-assert-methods-in-unit-tests/
网友评论