代码之家  ›  专栏  ›  技术社区  ›  Vijayadhas Chandrasekaran

Espresso测试框架匹配(isDisplayed())引发错误

  •  0
  • Vijayadhas Chandrasekaran  · 技术社区  · 6 年前

    我对浓缩咖啡测试很陌生。我在做下面的测试。

    1)是否显示文本视图

    2)文本视图值正确

    3)执行按钮点击。

    我正在使用以下代码。

    @Test
    public void validateTextView() {    
    
        //To check textview text value is correct
        onView(withId(R.id.textView1)).check(matches(withText("Hello World!")));
    
        //To check button click is working
        onView(withId(R.id.testButton)).perform(click());
    
        //To check textview is visible or not
        onView(withId(R.id.textView1)).check(matches(isDisplayed()));
    }
    

    但我错了 onView(withId(R.id.textView1)).check(matches(isDisplayed()));

    错误是

    android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with text: is "Hello World!"
    
    View Hierarchy:
    +>DecorView{id=-1, visibility=VISIBLE, width=1080, height=1920, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params={(0,0)(fillxfill) ty=BASE_APPLICATION wanim=0x10302f8
    fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
    pfl=FORCE_DRAW_STATUS_BAR_BACKGROUND}, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=3}
    |
    +->LinearLayout{id=-1, visibility=VISIBLE, width=1080, height=1794, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.FrameLayout$LayoutParams@bc95986, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
    |
    +-->ViewStub{id=16908682, res-name=action_mode_bar_stub, visibility=GONE, width=0, height=0, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=true, is-selected=false, layout-params=android.widget.LinearLayout$LayoutParams@1a62247, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0}
    |
    +-->FrameLayout{id=-1, visibility=VISIBLE, width=1080, height=1731, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.LinearLayout$LayoutParams@8cdb9d, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=63.0, child-count=1}
    |
    +--->ActionBarOverlayLayout{id=2131165227, res-name=decor_content_parent, visibility=VISIBLE, width=1080, height=1731, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.FrameLayout$LayoutParams@78bb9e0, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
    |
    +---->ContentFrameLayout{id=16908290, res-name=content, visibility=VISIBLE, width=1080, height=1584, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.support.v7.widget.ActionBarOverlayLayout$LayoutParams@9bc135e, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=147.0, child-count=1}
    |
    +----->ConstraintLayout{id=-1, visibility=VISIBLE, width=1080, height=1584, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.FrameLayout$LayoutParams@c1ce155, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
    |
    +------>AppCompatTextView{id=2131165288, res-name=secondTextView, visibility=VISIBLE, width=721, height=140, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.support.constraint.ConstraintLayout$LayoutParams@1b2076a, tag=null, root-is-layout-requested=false, has-input-connection=false, x=180.0, y=722.0, text=Second Activity, input-type=0, ime-target=false, has-links=false}
    |
    +------>AppCompatButton{id=2131165307, res-name=testButton, visibility=VISIBLE, width=300, height=126, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=false, is-selected=false, layout-params=android.support.constraint.ConstraintLayout$LayoutParams@d0ba45b, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, text=Test Button, input-type=0, ime-target=false, has-links=false}
    |
    +---->ActionBarContainer{id=2131165193, res-name=action_bar_container, visibility=VISIBLE, width=1080, height=147, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.support.v7.widget.ActionBarOverlayLayout$LayoutParams@d613036, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
    |
    +----->Toolbar{id=2131165191, res-name=action_bar, visibility=VISIBLE, width=1080, height=147, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.FrameLayout$LayoutParams@680e60d, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}
    |
    +------>AppCompatTextView{id=-1, visibility=VISIBLE, width=573, height=71, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.support.v7.widget.Toolbar$LayoutParams@60819c2, tag=null, root-is-layout-requested=false, has-input-connection=false, x=42.0, y=38.0, text=EspressoTestingSample, input-type=0, ime-target=false, has-links=false}
    |
    +------>ActionMenuView{id=-1, visibility=VISIBLE, width=0, height=147, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.support.v7.widget.Toolbar$LayoutParams@75843d3, tag=null, root-is-layout-requested=false, has-input-connection=false, x=1080.0, y=0.0, child-count=0}
    |
    +----->ActionBarContextView{id=2131165199, res-name=action_context_bar, visibility=GONE, width=0, height=0, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=true, is-selected=false, layout-params=android.widget.FrameLayout$LayoutParams@d715b10, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=0}
    |
    +->View{id=16908336, res-name=navigationBarBackground, visibility=VISIBLE, width=1080, height=126, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.FrameLayout$LayoutParams@162d609, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=1794.0}
    |
    +->View{id=16908335, res-name=statusBarBackground, visibility=VISIBLE, width=1080, height=63, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=android.widget.FrameLayout$LayoutParams@842100e, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0}
    |
    at dalvik.system.VMStack.getThreadStackTrace(Native Method)
    at java.lang.Thread.getStackTrace(Thread.java:1538)
    at android.support.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:88)
    at android.support.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:51)
    at android.support.test.espresso.ViewInteraction.waitForAndHandleInteractionResults(ViewInteraction.java:312)
    at android.support.test.espresso.ViewInteraction.check(ViewInteraction.java:297)
    at com.example.admin1.espressotestingsample.ExampleInstrumentedTest.validateTextView(ExampleInstrumentedTest.java:42)
    at java.lang.reflect.Method.invoke(Native Method)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:527)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at android.support.test.runner.AndroidJUnit4.run(AndroidJUnit4.java:101)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
    at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
    at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:384)
    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2145)
    

    但当我尝试 onView(withId(R.id.testButton)).check(matches(isDisplayed()));

    我很困惑。它在为巴顿工作。但不为textview工作。文本视图和按钮都在同一页中。请帮我解决这个问题。

    2 回复  |  直到 6 年前
        1
  •  0
  •   Relaxo    6 年前

    我认为错误不是来自:

    onView(withId(R.id.textView1)).check(matches(isDisplayed()));

    发布的错误消息的第一行是:

    android.support.test.espresso.NoMatchingViewException: No views in
    hierarchy found matching: with text: is "Hello World!"
    

    所以从第二行抛出异常。textview真的包含“hello world”吗?如果您查看错误消息的视图层次结构,则似乎不是这样。您的textview似乎包含文本“second activity”。

    请检查textview是否真的包含了预期的文本。通常很简单 check() 这应该能像预期的那样工作。

        2
  •  0
  •   Prince Dholakiya    6 年前

    我想这是你的解决办法

    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
    

    测试中的条件逻辑是不可取的。有鉴于此,espresso的api被设计用来引导测试作者远离它(通过显式地使用测试操作和断言)。

    尽管如此,您仍然可以通过实现自己的viewaction并将isdisplayed检查(在perform方法中)捕获到一个atomicboolean来实现上述目标。

    另一个不太优雅的选项-捕获失败检查引发的异常: