数据绑定导致Espresso测试失败 [英] Espresso test fails due to Data binding
问题描述
这是我的viewmodel类:
This is my viewmodel class :
class MainViewModel(
private val schedulerProvider: BaseSchedulerProvider,
private val api : StorytelService
) : BaseViewModel() {
private val _posts = MutableLiveData<List<Post>>()
val posts: LiveData<List<Post>>
get() = _posts
private val _status = MutableLiveData<Status>()
val status: LiveData<Status>
get() = _status
init {
showPhotos()
}
fun showPhotos() {
EspressoIdlingResource.increment() // App is busy until further notice
_status.postValue(Status.LOADING)
compositeDisposable.add(api.getPhotos()
.subscribeOn(schedulerProvider.io())
.observeOn(schedulerProvider.ui())
.doFinally {
if (!EspressoIdlingResource.countingIdlingResource.isIdleNow) {
EspressoIdlingResource.decrement() // Set app as idle.
}
}
.subscribe({
_status.postValue(Status.SUCCESS)
showPosts(it)
}) {
_status.postValue(Status.ERROR)
Timber.e(it)
})
}
private fun showPosts(networkPhotos: List<NetworkPhoto>) {
EspressoIdlingResource.increment() // App is busy until further notice
_status.postValue(Status.LOADING)
compositeDisposable.add(api.getPosts()
.subscribeOn(schedulerProvider.io())
.observeOn(schedulerProvider.ui())
.doFinally {
if (!EspressoIdlingResource.countingIdlingResource.isIdleNow) {
EspressoIdlingResource.decrement() // Set app as idle.
}
}
.subscribe({ networkPosts ->
_status.postValue(Status.SUCCESS)
_posts.postValue(
PostAndImages(networkPosts, networkPhotos).asDomaineModel()
)
}) {
_status.postValue(Status.ERROR)
Timber.e(it)
})
}
这是我的recyclerView布局:
This is my recyclerView in layout :
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:showData="@{vm.status}"
tools:listitem="@layout/post_item" />
这是绑定适配器:
@BindingAdapter("showData")
fun View.showData(status: Status) {
visibility = if (status == Status.SUCCESS) View.VISIBLE else View.GONE
}
您注意到我正在使用EspressoIdlingResource,但是当我按照espresso测试运行时,它失败了:
As you notice I am using EspressoIdlingResource, but when I run following espresso test, it fails :
@Test
fun shouldBeAbleToLoadList() {
onView(withId(R.id.recycler_view)).check(matches(isDisplayed()))
}
如果在测试开始时添加Thread.sleep(5000),它将起作用.如何解决?
If I add Thread.sleep(5000) in the beginning of the test, it works. How to resolve it?
推荐答案
使用Idling Resource
应该可以,但是它们有些乏味.
It should be possible with Idling Resource
however they are a little bit tedious.
我刚刚更新了旧的viewMatcher代码:
I've just updated an old viewMatcher code:
/**
* Perform action of waiting for a specific view id to be displayed.
* @param viewId The id of the view to wait for.
* @param millis The timeout of until when to wait for.
*/
public static ViewAction waitDisplayed(final int viewId, final long millis) {
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isRoot();
}
@Override
public String getDescription() {
return "wait for a specific view with id <" + viewId + "> has been displayed during " + millis + " millis.";
}
@Override
public void perform(final UiController uiController, final View view) {
uiController.loopMainThreadUntilIdle();
final long startTime = System.currentTimeMillis();
final long endTime = startTime + millis;
final Matcher<View> matchId = withId(viewId);
final Matcher<View> matchDisplayed = isDisplayed();
do {
for (View child : TreeIterables.breadthFirstViewTraversal(view)) {
if (matchId.matches(child) && matchDisplayed.matches(child)) {
return;
}
}
uiController.loopMainThreadForAtLeast(50);
}
while (System.currentTimeMillis() < endTime);
// timeout happens
throw new PerformException.Builder()
.withActionDescription(this.getDescription())
.withViewDescription(HumanReadables.describe(view))
.withCause(new TimeoutException())
.build();
}
};
}
那你只应该做:
@Test
fun shouldBeAbleToLoadList() {
onView(isRoot()).perform(waitDisplayed(R.id.recycler_view, 5000));
}
5000的超时时间为5秒(5000毫秒),您可以根据需要进行更改.
the 5000 is a timeout of 5 secs (5000 millis), you can change it if you want to.
执行waitDisplayed
后,可能会显示该元素或已达到超时.在最后一种情况下,将抛出Exception
.
After waitDisplayed
is executed it could happen that the element is shown or the timeout has been reached. In the last case an Exception
will be thrown.
这篇关于数据绑定导致Espresso测试失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!