我有以下情况。我们使用 Gherkin 语言通过 Espresso 驱动我们的原生 UI 自动化。在我们的 Gherkin 系列中,我们有一行叫做:
And I tap on button "Next"
其中“Next”是我们传递到胶水代码中的变量字符串(我们使用的是 Cucumber 框架)。
碰巧,我们的应用程序有许多具有不同资源 ID 的“下一步”按钮。我最终使用了带有如下变量的小 cucumber 线:
And I tap on button "Next in screen 1"
And I tap on button "Next in screen 2"
现在我只想在我的代码中使用 Gherkin 变量“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();
}
}
最佳答案
根据你的问题
My question is:
Is there a better approach which we can use to loop through it to see which id is displayed and if so click on it?
In my mind I came up with this idea, but it is not integrated in Espresso:
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))));
}
}
如您所见,在 Espresso 中使用 foreach
是可能的,但是不要使用 exists()
使用 check(matches(...)
值为:isDisplayed
、isDisplayedAtLeast
或 isCompletelyDisplayed
希望对你有帮助
关于android - 检查是否显示了数组中 View 中的资源 ID 并单击它 (Android-Espresso),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39125456/