检查是否显示了数组中视图中的资源 ID,然后单击它 (Android-Espresso)

Check if a resource id from view in array is displayed and click on it (Android-Espresso)

我有以下案例。我们正在使用 Gherkin 语言通过 Espresso 驱动我们的原生 ui 自动化。在我们的 Gherkin 行中,我们有一行名为:

And I tap on button "Next"

其中 "Next" 是我们传递给胶水代码的变量字符串(我们使用的是 Cucumber 框架)。

碰巧,我们的应用程序有许多 "Next" 个具有不同资源 ID 的按钮。我最终使用了带有变量的小黄瓜线,例如:

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))));

    }

}

如您所见,可以将 foreach 与 Espresso 一起使用,但不要使用 exists(),而应使用 check(matches(...),值:isDisplayedisDisplayedAtLeastisCompletelyDisplayed

希望对您有所帮助