我有以下情况。我们使用Gherkin语言通过Espresso推动我们的原生ui自动化。在我们的Gherkin系列中,我们有一行名为:
And I tap on button "Next"
其中“Next”是一个变量String我们传递给我们的胶水代码(我们使用的是Cucumber框架)。
碰巧,我们的应用程序有许多“下一步”按钮,具有不同的资源ID。最后我使用了带有变量的小黄瓜线:
And I tap on button "Next in screen 1"
And I tap on button "Next in screen 2"
现在我想在我的代码中只使用Gherkin变量“Next”。我得到一个Integer数组,其中包含来自所有Next按钮的所有资源id,但是当我想检查屏幕上显示哪个id时,我得到了NoMatchingViewException。
这是我目前的解决方案:
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,如果是,点击它?
在我看来,我提出了这个想法,但它没有集成在Espresso中:
for(int id : uiElementIds) {
if(onView(withId(id)).exist()) {
performClick();
}
}
答案 0 :(得分: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
使用Espresso,但exists()
代替check(matches(...)
使用值isDisplayed
,isDisplayedAtLeast
或{{1} isCompletelyDisplayed
}}
希望它能帮到你