android - 检查是否显示了数组中 View 中的资源 ID 并单击它 (Android-Espresso)

标签 android ui-automation android-espresso

我有以下情况。我们使用 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(...)值为:isDisplayedisDisplayedAtLeastisCompletelyDisplayed

希望对你有帮助

关于android - 检查是否显示了数组中 View 中的资源 ID 并单击它 (Android-Espresso),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39125456/

相关文章:

java - (JAVA) SOAP WebService 错误对象引用未设置到对象的实例

android - 以编程方式设置 PinEntryEditText 限制

android - Espresso 测试,点击 X/Y 坐标

java - 配置 Gradle 以加速 cordova-cli 构建

android - 由于每次启动时创建数据库而导致应用程序崩溃

javascript - 如何在 React Native 中截图测试?

java - 有没有办法在 TestNG 中设置全局参数?

c# - 关于 Appium 的问题

android - APK junit/runner/smalllogo.gif 中复制的重复文件

android - 检查 Espresso 是否显示对话框