首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Espresso不等待元素

Espresso不等待元素
EN

Stack Overflow用户
提问于 2017-01-18 16:20:33
回答 2查看 8K关注 0票数 3

我刚刚开始使用Espresso recorder。我做了我的第一个测试,从我看到的函数onView来看,假设等待对象继续不会完成工作。它总是返回:

android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching

有没有像wait for一样工作的函数,我可以用它代替?

代码语言:javascript
复制
package com.mytest;


import android.support.test.espresso.ViewInteraction;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import android.support.test.espresso.Espresso;
import android.support.test.espresso.IdlingResource;



import org.junit.Rule;
import org.junit.Test;
import org.junit.Before;
import org.junit.runner.RunWith;

import com.mytest.R;



import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition;
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.withParent;
import static org.hamcrest.Matchers.allOf;

@LargeTest
@RunWith(AndroidJUnit4.class)
public class Test1 {

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class);

    private IdlingResource mIdlingResource;

    @Before
    public void registerIdlingResource() {
        mIdlingResource = mActivityRule.getActivity().getIdlingResource();
        Espresso.registerIdlingResources(mIdlingResource);
    }

    @Test
    public void test1() {
        ViewInteraction recyclerView = onView(
                allOf(withId(R.id.recycler_view), isDisplayed()));
        recyclerView.perform(actionOnItemAtPosition(0, click()));

        ViewInteraction relativeLayout = onView(
                allOf(withId(R.id.capture_layout), isDisplayed()));
        relativeLayout.perform(click());

        ViewInteraction relativeLayout2 = onView(
                allOf(withId(R.id.like_layout),
                        withParent(allOf(withId(R.id.cameraLayout),
                                withParent(withId(android.R.id.content)))),
                        isDisplayed()));
        relativeLayout2.perform(click());

        ViewInteraction relativeLayout3 = onView(
                allOf(withId(R.id.exit_layout), isDisplayed()));
        relativeLayout3.perform(click());

    }
}
EN

回答 2

Stack Overflow用户

发布于 2018-05-08 00:32:25

一种方法是使用匹配器进行循环,直到它发生。当我需要等待异步任务完成时,我使用以下帮助程序。

代码语言:javascript
复制
public class ViewSynchronizer {
    private static final String TAG = "MC_Synchronizer";

    public static boolean viewExists(final Matcher<View> viewMatcher, final long millis) throws InterruptedException {
        final Boolean[] found = new Boolean[1];

        final CountDownLatch latch = new CountDownLatch(1);
        ViewAction action = new ViewAction() {
            @Override
            public Matcher<View> getConstraints() {
                return isRoot();
            }

            @Override
            public String getDescription() {
                return "wait for a specific view with id <" + viewMatcher.toString() + "> 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;


                do {
                    for (View child : TreeIterables.breadthFirstViewTraversal(view)) {

                        if (viewMatcher.matches(child)) {
                            Log.d(TAG, "perform: found match");
                            found[0] = true;
                            latch.countDown();
                            return;
                        }
                    }

                    uiController.loopMainThreadForAtLeast(50);
                }
                while (System.currentTimeMillis() < endTime);

                found[0] = false;
                latch.countDown();
            }
        };
        onView(isRoot()).perform(action);

        latch.await();
        return found[0];
    }
}

用法:

代码语言:javascript
复制
 Assert.assertTrue(viewExists(allOf(withId(R.id.account_sign_out_btb),withEffectiveVisibility(ViewMatchers.Visibility.GONE)),2000)); //wait 2 seconds
票数 2
EN

Stack Overflow用户

发布于 2017-01-18 21:40:05

更新:看起来像是在使用RecyclerView,请尝试下面的代码。

此外,如果您进行任何网络调用,您需要实现回收视图/网络IdlingResource,以告诉Espresso在执行测试步骤之前等待数据填充。

代码语言:javascript
复制
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class, true, true);

    private MainActivity mMainActivity = null;
    private IdlingResource mIdlingResource;

    @Before
    public void registerIdlingResource() {
        mMainActivity = mActivityRule.getActivity();
    }

    @Test
    public void test1() {

        mIdlingResource = mActivityRule.getActivity().getIdlingResource();
        Espresso.registerIdlingResources(mIdlingResource);

        mActivityRule.launchActivity(MainActivity.createIntent(getTargetContext()));

        ViewInteraction recyclerView = onView(
                allOf(withId(R.id.recycler_view), isDisplayed()));
        recyclerView.perform(actionOnItemAtPosition(0, click()));

        ViewInteraction relativeLayout = onView(
                allOf(withId(R.id.capture_layout), isDisplayed()));
        relativeLayout.perform(click());

        ViewInteraction relativeLayout2 = onView(
                allOf(withId(R.id.like_layout),
                        withParent(allOf(withId(R.id.cameraLayout),
                                withParent(withId(android.R.id.content)))),
                        isDisplayed()));
        relativeLayout2.perform(click());

        ViewInteraction relativeLayout3 = onView(
                allOf(withId(R.id.exit_layout), isDisplayed()));
        relativeLayout3.perform(click());

        Espresso.unregisterIdlingResources(mIdlingResource);

    }

使用ActivityTestRule时,您需要设置initialTouchMode和launchActivity。

使用这个

代码语言:javascript
复制
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class, true, true);

另外,别忘了在@After测试方法中取消注册IdlingResources。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41714389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档