2016-09-22 98 views
5

我需要向下滾動通過我的NestedScrollView爲了測試我的xml文件與Espresso,但我得到錯誤消息:」錯誤執行'滾動到'查看'與ID:「咖啡測試NestedScrollView - 「錯誤執行」滾動到'視圖'與id:「

其他幾個似乎有類似問題的帖子。從這個

我按照說明:Android espresso NestedScrollView, how to scroll to bottom

現在我得到的forementioned錯誤,發現這個帖子:Scrolling to view was attempted, but the view is not displayed

我在NestedScrollView沒有填充 - 我甚至嘗試從XML產品總數去除填充,用於測試目的,但沒有區別。

這是我的測試(到目前爲止,這是不應該做的事情,但向下滾動):

@Test 
    public void testScrollDownAbilityOfDetailsScrollView(){ 
     goToSpecificItemOnStream(streamItemWithOneImage); 

     onView(withId(R.id.end_of_details)) 
       .perform(ScrollToAction.betterScrollTo()); 

    } 

它使用由滾動自定義要Action類:

public final class ScrollToAction implements ViewAction { 

    private static final String TAG = ScrollToAction.class.getSimpleName(); 

    @SuppressWarnings("unchecked") 
    @Override 
    public Matcher<View> getConstraints() { 
     return allOf(withEffectiveVisibility(Visibility.VISIBLE), isDescendantOfA(anyOf(
       isAssignableFrom(ScrollView.class), isAssignableFrom(HorizontalScrollView.class), isAssignableFrom(NestedScrollView.class)))); 
    } 

    @Override 
    public void perform(UiController uiController, View view) { 
     if (isDisplayingAtLeast(80).matches(view)) { 
      Log.i(TAG, "View is already displayed. Returning."); 
      return; 
     } 
     Rect rect = new Rect(); 
     view.getDrawingRect(rect); 
     if (!view.requestRectangleOnScreen(rect, true /* immediate */)) { 
      Log.w(TAG, "Scrolling to view was requested, but none of the parents  scrolled."); 
     } 
     uiController.loopMainThreadUntilIdle(); 
     if (!isDisplayingAtLeast(80).matches(view)) { 
      throw new PerformException.Builder() 
        .withActionDescription(this.getDescription()) 
        .withViewDescription(HumanReadables.describe(view)) 
        .withCause(new RuntimeException(
          "Scrolling to view was attempted, but the view is not displayed")) 
        .build(); 
     } 
    } 
    public static ViewAction betterScrollTo() { 
     return ViewActions.actionWithAssertions(new ScrollToAction()); 
    } 

    @Override 
    public String getDescription() { 
     return "scroll to"; 
    }} 

定製由於正常的scrollTo方法被硬編碼爲ScrollView和Horizo​​ntalScrollView,而不是NestedScrollView,所以有了ScrollToAction類。

這是我想測試的XML文件:

 <?xml version="1.0" encoding="utf-8"?> 
     <android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
     xmlns:app="http://schemas.android.com/apk/res-auto" 
     android:id="@+id/scrollView" 
     xmlns:tools="http://schemas.android.com/tools" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     app:layout_behavior="@string/appbar_scrolling_view_behavior"> 

     <RelativeLayout 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:orientation="horizontal"> 



      <FrameLayout 
       android:id="@+id/fl" 
       android:background="#FBFBFB" 
       android:layout_margin="0dp" 
       android:layout_width="match_parent" 
       android:layout_height="350dp"> 

       <android.support.v4.view.ViewPager 
        android:id="@+id/container" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 

       <ImageView 
        android:id="@+id/location" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_margin="@dimen/text_margin" 
        android:layout_gravity="left|top" 
        android:background="@null" 
        android:src="@drawable/ic_location_white" 
        android:paddingLeft="-8dp" /> 


       <TextView 
        android:id="@+id/textViewDistance" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_toRightOf="@id/location" 
        android:textAppearance="?android:attr/textAppearanceMedium" 
        android:layout_margin="@dimen/text_margin" 
        android:layout_gravity="left|top" 
        android:shadowColor="#262424" 
        android:shadowDx="1" 
        android:shadowDy="1" 
        android:shadowRadius="2" 
        android:textColor="#FBFBFB" 
        android:textSize="22dp" 
        android:singleLine="false" 
        android:paddingLeft="24dp" /> 


       <TextView 
        android:id="@+id/textViewPrice" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:textAppearance="?android:attr/textAppearanceMedium" 
        android:layout_margin="@dimen/text_margin" 
        android:layout_gravity="right|top" 
        android:shadowColor="#262424" 
        android:shadowDx="1" 
        android:shadowDy="1" 
        android:shadowRadius="2" 
        android:textColor="#FBFBFB" 

        android:textSize="22dp"/> 

       <me.relex.circleindicator.CircleIndicator 
        android:id="@+id/indicator" 
        android:layout_width="match_parent" 
        android:layout_height="40dp" 
        android:layout_gravity="bottom" 
        android:shadowColor="#262424" 
        android:shadowDx="1" 
        android:shadowDy="1" 
        android:shadowRadius="1"/> 



      </FrameLayout> 


      <LinearLayout 

       android:layout_below="@id/fl" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:orientation="vertical" 
       > 

       <TextView 
        android:id="@+id/textViewTitle" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:gravity="left" 
        android:layout_margin="@dimen/text_margin" 
        android:textColor="@color/colorCheckTomBlack" 
        android:textStyle="bold" 
        android:textSize="20dp" /> 

       <TextView 
        android:id="@+id/textViewDescription" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_marginLeft="@dimen/text_margin" 
        android:layout_marginRight="@dimen/text_margin" 
        android:gravity="left" 
        android:textColor="@color/colorCheckTomBlack" 
        android:textSize="18dp" 
        android:layout_weight="0.56" /> 

       <RelativeLayout 
        android:layout_width="match_parent" 
        android:layout_height="65dp" 
        android:paddingTop="30dp"> 


        <ImageButton 
         android:id="@+id/buttonWatchlist" 
         android:src="@drawable/ic_checktom" 
         android:background="@null" 
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:gravity="left" 
         android:layout_marginLeft="55dp" 
         android:layout_marginStart="55dp" 
         android:layout_alignParentTop="true" 
         android:layout_alignParentLeft="true" 
         android:layout_alignParentStart="true" 
         android:onClick="launchWatchlistActivity" 
         android:paddingTop="2dp"/> 


        <ImageButton 
         android:id="@+id/buttonMessage" 
         android:src="@drawable/ic_messages" 
         android:background="@null" 
         android:scaleX="1.2" 
         android:scaleY="1.2" 
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:layout_gravity="center_horizontal" 
         android:layout_alignParentTop="true" 
         android:layout_centerHorizontal="true" 
         android:onClick="launchMessageActivity" 
         android:paddingTop="7dp"/> 


        <ImageButton 
         android:id="@+id/buttonShare" 
         android:src="@drawable/ic_share" 
         android:background="@null" 
         android:scaleX="1.5" 
         android:scaleY="1.5" 
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:layout_marginRight="54dp" 
         android:layout_marginEnd="54dp" 
         android:layout_alignParentTop="true" 
         android:layout_alignParentRight="true" 
         android:layout_alignParentEnd="true" 
         android:onClick="launchShareActivity"/> 



       </RelativeLayout> 


       <RelativeLayout 
        android:orientation="horizontal" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:padding="2dp"> 


        <TextView 
         android:id="@+id/textViewWatchlist" 
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:text="Watchlist" 
         android:layout_marginLeft="41dp" 
         android:layout_marginStart="41dp" 
         android:layout_alignParentTop="true" 
         android:layout_alignParentLeft="true" 
         android:layout_alignParentStart="true" /> 


        <TextView 
         android:id="@+id/textViewMessage" 
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:text="Message" 
         android:layout_gravity="center_horizontal" 
         android:layout_alignParentTop="true" 
         android:layout_centerHorizontal="true" /> 

        <TextView 
         android:id="@+id/textViewShare" 
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:text="Share" 
         android:layout_gravity="center_horizontal" 
         android:layout_alignParentTop="true" 
         android:layout_alignParentRight="true" 
         android:layout_alignParentEnd="true" 
         android:layout_marginRight="52dp" 
         android:layout_marginEnd="52dp" /> 


       </RelativeLayout> 
       <LinearLayout 
        android:orientation="horizontal" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_gravity="center"> 


       <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="_________________________________________" 
        android:paddingTop="25dp"/> 


       </LinearLayout> 

       <LinearLayout 
        android:orientation="horizontal" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_gravity="center"> 

        <de.hdodenhof.circleimageview.CircleImageView 
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:layout_below="@+id/imageView" 
         android:layout_centerHorizontal="true" 
         android:id="@+id/circleView" 
         android:scaleX="0.4" 
         android:scaleY="0.4" 
         android:layout_marginTop="-20dp" 
         android:layout_marginBottom="-60dp" 
         />  

       </LinearLayout> 

       <LinearLayout 
        android:orientation="vertical" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:layout_gravity="center">  
        <LinearLayout 
         android:orientation="horizontal" 
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:layout_gravity="center">  
        <TextView 
         android:id="@+id/textViewSellerName" 
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:textSize="18dp"/>  
         </LinearLayout>   
        <LinearLayout 
         android:orientation="horizontal" 
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:layout_gravity="center">  
        <TextView 
         android:id="@+id/textViewSellerDestination" 
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:paddingBottom="20dp" />  
         <TextView 
          android:id="@+id/end_of_details" 
          android:layout_width="match_parent" 
          android:layout_height="wrap_content" /> 
         </LinearLayout>   
       </LinearLayout> 
      </LinearLayout> 
     </RelativeLayout> 
    </android.support.v4.widget.NestedScrollView> 

如果測試失敗,這是完整的輸出我得到:

android.support.test.espresso。 PerformException:在視圖上執行'滾動到'時出錯:id:com.checktom.checktom:id/end_of_details'。 at android.support.test.espresso.PerformException $ Builder.build(PerformException.java:83) at android.support.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:80) at android.support。 test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:56) at android.support.test.espresso.ViewInteraction.runSynchronouslyOnUiThread(ViewInteraction.java:184) at android.support.test.espresso.ViewInteraction.doPerform( ViewInteraction.java:115) 在android.support.test.espresso.ViewInteraction.perform(ViewInteraction.java:87) 在com.checktom.checktom.ApplicationTest.testScrollDownAbilityOfDetailsS​​crollView(ApplicationTest.java:279) 在java.lang中。反映。方法。啓動(本地方法) at java.lang.reflect.Method.invoke(Method.java:372) 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.internal.statement.UiThreadStatement.evaluate(UiThreadStatement.java:55) at android .support.test.rule.ActivityTestRule $ ActivityStatement.evaluate(ActivityTestRule.java:270) 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) 在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290) 在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.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)在org.junit.runners.ParentRunner.access處使用org.junit.runners.runners.ParentRunner $ 1.schedule(ParentRunner.java:71) org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) $ 000( (org.junit.runners.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:59 ) at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262) at android.app.Instrumentation $ InstrumentationThread.run(Instrumentation.ja va:1933) 引起:java.lang.RuntimeException:嘗試滾動查看,但未在android.support處顯示視圖 at com.checktom.checktom.ScrollToAction.perform(ScrollToAction.java:52) 。 test.espresso.ViewInteraction $ 1.run(ViewInteraction.java:144) 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:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:145 ) at android.app.ActivityThread.main(ActivityThread.java:6938) at java.lang.reflect.Method.invoke(Native Method) 在java.lang.reflect.Method.invoke(Method.java:372) 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1404) 在com.android.internal.os。 ZygoteInit.main(ZygoteInit.java:1199) 測試運行完成。

我可以告訴我在我的ScrollToAction類的perform方法中遇到了運行時異常,但我還沒有找到解決方法。

在我鏈接的第一篇文章中,新的BetterScrollTo方法似乎像魅力一樣工作。

+1

試這個http://stackoverflow.com/questions/35272953/espresso-scrolling-not-working-when-nestedscrollview-or-recyclerview-is-in-coor –

+1

那是其中一個帖子,我已經遵循。但是,謝謝你:) 它提出了兩件事。首先,你應該創建自己的ScrollToAction類,我已經完成了,還有兩個,即CoordinatorLayout中的NestedScrollView可能會導致問題,但是我的NestedScrollView不在CoordinatorLayout中。 儘管謝謝你的努力! – Silas

+0

編輯: 看過我的NestedScrollView父母后,我發現它實際上是在一個CoordinatorLayout中。雖然它不是CoordinatorLayout的直接子元素,所以在帖子中提到的getParent()方法對我不起作用。 – Silas

回答

1

我這樣做:

onView(withId(R.id.viewToScroll) 
       .perform(nestedScrollTo()) 
       .check(matches(isDisplayed())); 

其中nestedScrollTo()是:

public static ViewAction nestedScrollTo() { 
    return new ViewAction() { 

     @Override 
     public Matcher<View> getConstraints() { 
      return Matchers.allOf(
        isDescendantOfA(isAssignableFrom(NestedScrollView.class)), 
        withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)); 
     } 

     @Override 
     public String getDescription() { 
      return "View is not NestedScrollView"; 
     } 

     @Override 
     public void perform(UiController uiController, View view) { 
      try { 
       NestedScrollView nestedScrollView = (NestedScrollView) 
         findFirstParentLayoutOfClass(view, NestedScrollView.class); 
       if (nestedScrollView != null) { 
        nestedScrollView.scrollTo(0, view.getTop()); 
       } else { 
        throw new Exception("Unable to find NestedScrollView parent."); 
       } 
      } catch (Exception e) { 
       throw new PerformException.Builder() 
         .withActionDescription(this.getDescription()) 
         .withViewDescription(HumanReadables.describe(view)) 
         .withCause(e) 
         .build(); 
      } 
      uiController.loopMainThreadUntilIdle(); 
     } 

    }; 
} 

private static View findFirstParentLayoutOfClass(View view, Class<? extends View> parentClass) { 
    ViewParent parent = new FrameLayout(view.getContext()); 
    ViewParent incrementView = null; 
    int i = 0; 
    while (parent != null && !(parent.getClass() == parentClass)) { 
     if (i == 0) { 
      parent = findParent(view); 
     } else { 
      parent = findParent(incrementView); 
     } 
     incrementView = parent; 
     i++; 
    } 
    return (View) parent; 
} 

private static ViewParent findParent(View view) { 
    return view.getParent(); 
} 

private static ViewParent findParent(ViewParent view) { 
    return view.getParent(); 
}