2015-09-03 68 views
16

我想寫一個咖啡功能,以匹配第一個元素咖啡發現根據我的功能,即使當發現多個匹配項目。咖啡比賽第一個元素髮現時,許多人在層次結構

例如: 我有一個列表視圖,其中包含項目價格的單元格。我希望能夠將貨幣轉換爲加元,並驗證項目價格是以加元計算的。

我使用這個功能:

onView(anyOf(withId(R.id.product_price), withText(endsWith("CAD")))) 
     .check(matches(
       isDisplayed())); 

這將引發AmbiguousViewMatcherException。

在這種情況下,我不在乎多少個或幾個單元顯示CAD,我只是想驗證它顯示。一旦遇到符合參數的物體,是否有辦法使咖啡通過此測試?

回答

18

您應該能夠創建一個只用下面的代碼中的第一項匹配的定製匹配:

private <T> Matcher<T> first(final Matcher<T> matcher) { 
    return new BaseMatcher<T>() { 
     boolean isFirst = true; 

     @Override 
     public boolean matches(final Object item) { 
      if (isFirst && matcher.matches(item)) { 
       isFirst = false; 
       return true; 
      } 

      return false; 
     } 

     @Override 
     public void describeTo(final Description description) { 
      description.appendText("should return first matching item"); 
     } 
    }; 
} 
1

據我瞭解,在方案中所有的價格應該在CAD您已切換後貨幣。因此,只要抓住了第一個項目,並驗證它應該解決您的問題太多:

onData(anything()) 
     .atPosition(0) 
     .onChildView(allOf(withId(R.id.product_price), withText(endsWith("CAD")))) 
     .check(matches(isDisplayed())); 
2

我創造了這個匹配的情況下,你有喜歡相同的ID相同特性的許多元素,並如果你想不只是第一個元素而是想要一個特定元素。希望這有助於:

private static Matcher<View> getElementFromMatchAtPosition(final Matcher<View> matcher, final int position) { 
    return new BaseMatcher<View>() { 
     int counter = 0; 
     @Override 
     public boolean matches(final Object item) { 
      if (matcher.matches(item)) { 
       if(counter == position) { 
        counter++; 
        return true; 
       } 
       counter++; 
      } 
      return false; 
     } 

     @Override 
     public void describeTo(final Description description) { 
      description.appendText("Element at hierarchy position "+position); 
     } 
    }; 
} 

例子:

你必須與你使用的是庫提供相同的ID多的按鈕,你要選擇第二個按鈕。

ViewInteraction colorButton = onView(
      allOf(
        getElementFromMatchAtPosition(allOf(withId(R.id.color)), 2), 
        isDisplayed())); 
    colorButton.perform(click());