2016-08-24 40 views
4

我有以下情况。我们使用小黄瓜语言通过Espresso驱动我们的本地UI自动化。在我们的小黄瓜线,我们已经有了一个叫行:检查是否显示数组中的资源ID并点击它(Android-Espresso)

And I tap on button "Next" 

其中,“下一步”是一个可变的字符串,我们通过到我们的胶水代码(我们使用的是黄瓜框架)。

碰巧,我们的应用程序有许多具有不同资源ID的“下一步”按钮。我结束了使用类似变量的小黄瓜线:

And I tap on button "Next in screen 1" 
And I tap on button "Next in screen 2" 

现在我想只在我的代码中使用小黄瓜变量“下一步”。我得到一个Integer数组,其中包含所有Next按钮的所有资源ID,但是当我想要检查屏幕上显示的是哪个ID时,我得到了一个N​​oMatchingViewException。

这是我目前的解决方案,现在:

final int[] uiElementIds = getArrayWithIdsFromUIElement("Next"); 

    int testId = 0; 
    for(int id : uiElementIds) { 
     try { 
      onView(withId(id)).check(matches(isDisplayed())); 
      testId = id; 
      break; 
     } catch(NoMatchingViewException ex) { 
      // do nothing 
     } 
    } 

    final int uiElementId = testId; 
    onView(withId(uiElementId)).withFailureHandler(new FailureHandler() { 
      @Override 
      public void handle(Throwable error, Matcher<View> viewMatcher) { 
       onView(withId(uiElementId)).perform(scrollTo(), click()); 
      } 
     }).perform(click()); 

正如你可以看到我正好赶上抛出NoMatchingViewException,什么也不做下去直到找到正确的ID,打破了for循环的。


我的问题是:

是否有更好的办法,我们可以用它来循环通过它看到的是显示其ID,如果是一下就可以了?

在我心目中,我想出了这个主意,但它没有集成在咖啡:

for(int id : uiElementIds) { 
if(onView(withId(id)).exist()) { 
    performClick(); 
} 
} 

回答

1

根据你的问题

我的问题是:

是有更好的方法,我们可以用它来循环查看哪个id被显示,如果是的话点击它?

在我心目中,我想出了这个主意,但它没有集成在 咖啡:

for(int id : uiElementIds) { 
if(onView(withId(id)).exist()) { 
    performClick(); 
} 
} 

这里是我的老Espresso框架Activity测试:

@RunWith(AndroidJUnit4.class) 
@FixMethodOrder(MethodSorters.NAME_ASCENDING) 
public class DetailsActivityTest { 

    @Rule 
    public ActivityTestRule<MainActivity_> mRule = new ActivityTestRule<>(MainActivity_.class); 

    //TODO: Write tests to check if views are visible 
    private final int[] allDetailsActivityViewsIdis = { 
      R.id.dItem, 
      R.id.dDayAndDate, 
      R.id.dDay, 
      R.id.dDate, 
      R.id.dCity, 
      R.id.dTempAndIcon, 
      R.id.dTemperature, 
      R.id.dHighTemp, 
      R.id.dLowTemp, 
      R.id.dDescriptionLayout, 
      R.id.dDescription, 
      R.id.dForecast, 
      R.id.dHumidityLayout, 
      R.id.dHumidityDesc, 
      R.id.dHumidityVal, 
      R.id.dPressureLayout, 
      R.id.dPressureDesc, 
      R.id.dPressureVal, 
      R.id.dWindLayout, 
      R.id.dWindDesc, 
      R.id.dWindVal 

    }; 

    private final int[] detailsActivityTextViewsIdis = { 
      R.id.dDay, 
      R.id.dDate, 
      R.id.dHighTemp, 
      R.id.dLowTemp, 
      R.id.dDescription, 
      R.id.dHumidityVal, 
      R.id.dPressureVal, 
      R.id.dWindVal, 

    }; 

    private final int[] detailsActivityTextViewsDefaultValues = { 
      R.string.day, 
      R.string.date, 
      R.string.high_temp, 
      R.string.low_temp, 
      R.string.description, 
      R.string.humidity_val, 
      R.string.pressure_val, 
      R.string.wind_val, 

    }; 

    @Before 
    //TODO: Rewrite this code using espresso-intents 
    public void checkIfAllDetailActivityViewsAreDisplayed() throws InterruptedException { 
     for (int viewId : allDetailsActivityViewsIdis) 
      onView(withId(viewId)).perform(click()); 

    } 

    @Test 
    public void checkIfDetailsActivityViewsHaveNoDefaultValue() throws InterruptedException { 
     for (int viewId : detailsActivityTextViewsIdis) 
      for (int valueId : detailsActivityTextViewsDefaultValues) 
       onView(withId(viewId)).check(matches(not(withText(valueId)))); 

    } 

} 

正如你看到的,使用foreach与浓咖啡是可能的,但代替exists()使用check(matches(...)与价值:isDisplayedisDisplayedAtLeastisCompletelyDisplayed

希望它能帮到你