Android Expresso/UI Automator 如何自动点击我的应用程序(应用程序选择器)外的 Android 屏幕

Android Expresso/UI Automator How do i automate clicking on Android screens outside my app (app picker)

我的 Android 应用程序有一个按钮可以下载文件,然后将其发送到设备上的应用程序。 Android 弹出一个屏幕,列出设备上的应用程序,供用户select 使用哪个应用程序。

我想自动执行此流程,但我看不到如何自动单击 Android 显示的应用程序选择器。我想这是因为它在我的应用程序之外。

我尝试使用 Android Studio 的 "Record Expresso Test",我执行了以下测试步骤

  1. 单击将我的图像发送到设备上的应用程序的操作(操作 1)
  2. 看到 Android 应用选择器出现并选择了照片
  3. 点击返回关闭照片应用程序并返回我的应用程序
  4. 点击我的应用程序中的不同操作(action2)

我在记录的测试代码中看到了上面的步骤 1 和 4,但没有看到步骤 2 和 3。因此这让我觉得 Expresso 不能用于这个特定的测试流程。

有谁知道我如何使用 Expresso 测试此流程?

编辑:

感谢 "John O'Reilly" 推荐 UI Automator。我可以看到我可以在我的 Expresso 测试中成功使用 UI Automator 代码。但是,我在编写应用程序选择器的精确验证时遇到问题。

select或将拥有 "Open With" 的标题。使用 Android Device Monitor 我可以看到 objects 的层次结构,如下图所示。

一些 类 和 ID 是内部的,所以我无法搜索那些东西。我不想编写代码来查找特定的应用程序,因为当测试在另一台机器上 运行 时,它可能没有该应用程序。我只需要验证是否显示了应用程序选择器。

// the app selector has a FrameLayout as one of its parent views, and a child Text View which has the "Open With" title
UiObject labelOnly = new UiObject(new UiSelector()
        .className("android.widget.FrameLayout")
        .childSelector(new UiSelector()
                .className("android.widget.TextView")
                .text(openWithLabel)
        )
);
boolean labelOnly_exists = labelOnly.exists();

// the app selector has a FrameLayout as one of its parent views, and a child ListView (containing the apps)
UiObject listOnly = new UiObject(new UiSelector()
        .className("android.widget.FrameLayout")
        .childSelector(new UiSelector()
                .className("android.widget.ListView")
        )
);
boolean listOnly_exists = listOnly.exists();  

// I can use the listView to search for a specific app, but this makes the tests fragile if a different device does not have that app installed
UiObject listAndAppName = new UiObject(new UiSelector()
        .className("android.widget.ListView")
        .instance(0)
        .childSelector(new UiSelector()
                .text("Photos")));
boolean listAndAppName_exists = listAndAppName.exists();

我如何编写一个语句来验证屏幕上显示的是应用程序选择器?我希望可能有一个 select 或者搜索一个 FrameLayout,它有一个包含 "Open With" 的 child textView 并且还包含一个 child ListView。通过这两项检查,它应该只识别应用程序选择器。

这个问题的答案应该归功于 John O'Reilly,他指导我使用 UI Automator。

我解决了检查 Android 屏幕在我的测试单击某个操作时被调用的问题,方法是检查屏幕上是否有一个带有我期望的标题的 TextView。它并不完美,因为如果屏幕上有任何带有文本的 TextView,这将通过,因此不会精确检查其应用程序选择器。

但是,对于我的测试来说,这应该足以进行检查,因为我的应用程序(将在应用程序选择器后面)不应该有带有预期标题的 TextView,所以如果找到标题,它很可能成为应用程序选择器。

public static boolean verifyAndroidScreenTitlePresent(String title) {
    UiDevice mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

    UiObject titleTextUI = new UiObject(new UiSelector()
            .className("android.widget.TextView")
            .text(title)
    );
    boolean titleExists = titleTextUI.exists();

    // close the app selector to go back to our app so we can carry on with Expresso
    mDevice.pressBack();

    return titleExists;
}