使用Espresso单击不完全可见的imageButton

时间:2015-03-03 14:40:13

标签: android testing android-espresso ui-testing

我有一个设计不完全可见的自定义ImageButton,所以当我执行点击操作时,我收到此错误:

android.support.test.espresso.PerformException: Error performing 'single click' on view 'with id: test.com.myproject.app:id/navigationButtonProfile'.
Caused by: java.lang.RuntimeException: Action will not be performed because the target view does not match one or more of the following constraints:
at least 90 percent of the view's area is displayed to the user.
at android.support.test.espresso.ViewInteraction$1.run(ViewInteraction.java:138)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)

按钮的一小部分位于屏幕之外(即顶部被裁剪),可能有12%的按钮位于屏幕之外。这是设计使然,无法滚动或执行任何视图操作以使其可见。 任何人都知道如何通过这个90%的约束?

解决方案: 我按照建议创建了自己的点击操作,效果很好。 我从Google Espresso复制了该类,并在此方法中将其从90更改为75:

    @Override
    @SuppressWarnings("unchecked")
    public Matcher<View> getConstraints() {
        Matcher<View> standardConstraint = isDisplayingAtLeast(75);
        if (rollbackAction.isPresent()) {
            return allOf(standardConstraint, rollbackAction.get().getConstraints());
        } else {
            return standardConstraint;
        }
    }

7 个答案:

答案 0 :(得分:50)

以上都不适合我。这是一个自定义匹配器,可以完全删除该约束,并允许您单击视图

 onView(withId(yourID)).check(matches(allOf( isEnabled(), isClickable()))).perform(
            new ViewAction() {
                @Override
                public Matcher<View> getConstraints() {
                    return ViewMatchers.isEnabled(); // no constraints, they are checked above
                }

                @Override
                public String getDescription() {
                    return "click plus button";
                }

                @Override
                public void perform(UiController uiController, View view) {
                    view.performClick();
                }
            }
    );

答案 1 :(得分:11)

您必须先滚动到按钮:

onView(withId(R.id.button_id)).perform(scrollTo(), click());

答案 2 :(得分:9)

我认为没有任何简单,优雅的解决方案。 90%的约束在GeneralClickAction中是硬编码的,并且该类是最终的,因此我们无法覆盖getConstraints

我会根据GeneralClickAction's code编写您自己的ViewAction,跳过isDisplayingAtLeast检查。

答案 3 :(得分:6)

默认点击Espresso需要查看视图> 90%。您如何看待创建自己的click ViewAction? 像这样......

public final class MyViewActions {
   public static ViewAction click() {
      return new GeneralClickAction(SafeTap.SINGLE, GeneralLocation.CENTER, Press.FINGER);
    }
}

此点击将点击视图的中心。

然后你可以像这样执行点击: onView(withId(....)).perform(MyViewActions.click());

我希望它能奏效。

答案 4 :(得分:6)

这有助于我在运行测试时解决按钮可见性

public static ViewAction handleConstraints(final ViewAction action, final Matcher<View> constraints)
{
    return new ViewAction()
    {
        @Override
        public Matcher<View> getConstraints()
        {
            return constraints;
        }

        @Override
        public String getDescription()
        {
            return action.getDescription();
        }

        @Override
        public void perform(UiController uiController, View view)
        {
            action.perform(uiController, view);
        }
    };
}

public void clickbutton()
{
    onView(withId(r.id.button)).perform(handleConstraints(click(), isDisplayingAtLeast(65)));
}

答案 5 :(得分:0)

对于在文本视图中遇到的相同错误,我最终如下进行操作,上面发布的答案以及其他SO问题也有很大帮助。我确实尝试了scrollTo方法,但是由于某种原因,错误仍然存​​在。希望这对某人有帮助。

        onView(allOf(withId(R.id.recycler_view), isDisplayed())).perform(RecyclerViewActions
                .actionOnItem(hasDescendant(withText("my text")), click()));

答案 6 :(得分:0)

创建您自己的没有视图可见性约束的 ViewAction 类:

 public static ViewAction myClick() {

    return new ViewAction() {
        @Override
        public Matcher<View> getConstraints() {
            return ViewMatchers.isEnabled(); // no constraints, they are checked above
        }

        @Override
        public String getDescription() {
            return null;
        }

        @Override
        public void perform(UiController uiController, View view) {
            view.performClick();
        }
    };

}

然后使用它:

onView(withId(R.id.your_view_id)).perform(myClick());