从应用程序内运行仪器测试并等待结果

Posted

技术标签:

【中文标题】从应用程序内运行仪器测试并等待结果【英文标题】:Run an instrument test from within app and wait for result 【发布时间】:2019-01-25 18:47:01 【问题描述】:

我正在开发一个 QA 自动化解决方案,可以在 android 上记录/回放 QA 测试。一个关键的业务要求是在回放记录的测试时不依赖连接的 PC。为此,我正在尝试在没有连接 PC 的情况下运行仪器测试。 (特别是 Appium UiAutomator2 测试)。

我目前的方法是尝试从我的应用程序以编程方式运行测试。如果我在连接的 PC 上正常运行测试,我会使用命令adb shell am instrument -w。我尝试从我的应用程序访问 ADB Shell 并运行 am instrument -w,但这会产生一个错误,我缺少 INTERACT_ACROSS_USERS_FULL 权限。

为了解决这个问题,我尝试使用startInstrumentation 运行测试。这样就成功开始了测试。但是,测试立即崩溃。经过进一步调查,我将崩溃追溯到 NPE:测试试图检索 InstrumentationRegistry.getInstrumentation.getUiAutomation(0),但这返回 null。

如何以编程方式运行测试并为其提供对所需 UiAutomation 实例的访问权限?

这就是我开始测试的方式:

public void runTest() 
    final String pm = getPackageName().replaceFirst(".test$", "");
    final InstrumentationInfo info = getInstrumentationInfo(pm);
    if (info != null) 

        final ComponentName cn = new ComponentName(info.packageName,
                info.name);

        Bundle arguments = new Bundle();
        arguments.putString("class", "io.testim.appiumwrapper.test.AppiumUiAutomator2Server");
        //cn = io.extension.test/android.support.test.runner.AndroidJUnitRunner
        startInstrumentation(cn, null, arguments);

     

【问题讨论】:

您是否要等待每次测试的通过或失败结果? 我尝试模仿 Appium 并运行一个测试服务器,该服务器一直运行到我杀死它为止。 为什么您不在应用程序中使用“adb shell am instrument -w”? 您无法从应用程序启动 adb shell 命令。谷歌阻止了它,它不再起作用了。 @MaorHadad 你有办法做到这一点吗? 【参考方案1】:

请参阅signature protection level - clarifying ...除非将包通过 Google 的发布密钥列入白名单,否则您将无法获得必要的许可。这是一个安全/完整性功能,目的是限制恶意软件能够做什么——以及你打算在那里做什么,是典型的恶意软件行为——无论它的实际意图是什么;与系统作对是无济于事的。

我可以成像的唯一方法是直接从终端仿真器或测试应用程序运行命令 - 针对 AOSP 的自定义构建,以便您可以将 android:protectionLevel="signature" 添加到 Manifest.xml 然后需要 @ 987654327@。但是使用库存ROM,绝对没有机会这样做。不是,这将是“不可能的”,但构建自定义 ROM 需要付出相当多的努力才能实现。至少对于NexusPixel 设备,所需的驱动程序可用here;对于其他设备,您必须在设备供应商处找到它们,如果它们甚至可用的话。

诀窍是使用与应用程序相同的密钥签署 ROM - 只有这样才能获得 signature 级别权限 - 而对于股票 ROM,您(理论上)需要 Google 的发布密钥来签署包裹。正如here 解释的那样,可以强制执行单个用户,而这也仅适用于系统应用程序。

【讨论】:

我的用例(和赏金)是创建可驱动其他应用程序的可访问性友好应用程序。例如 - 我可以为残疾人录制某些艰难的动作,然后他们会播放它们。尽管这可能被认为是有问题的,但这正是可访问性 API 应该让我做的事情(用户可以选择加入)。您可以开始测试但您只是等不及的事实表明这不是不可能的。无论如何,要求用户选择加入没有问题,但让他们安装另一个 ROM 是不切实际的。 @BenjaminGruenbaum 赏金不会改变 Android 操作系统定义的技术要求 - 我已经详细解释过。这是否可行或适用,不是问题的一部分。对我来说,整个概念看起来并不现实——因为它忽略了现实。使用运行 Android 模拟器的 x86 平板电脑可能是记录交互的唯一替代方式。 我会澄清的。启动 UIAutomator2 不会增加或减少 Android 或 OP 应用程序的任何功能。 OP 已经使用了 AccessibilityService,它(虽然需要许可)让您在技术上(几乎)完成 UIAutomator2 所做的所有事情。也就是说,可以在已经使用的 API 和权限之上重写所有这些代码,但这会浪费大量时间。所以这肯定不会与可能发生的事情“不一致”。 @BenjaminGruenbaum 错误消息应该类似于java.lang.SecurityException: Permission Denial: get/set setting for user asks to run as user -2 but is calling from user 0。这对于任何包都是不允许的,而无法获得那些signature级别的权限,只能通过包签名获得。要成为操作系统,需要拥有操作系统的签名密钥。 同样从Android 5.0开始,底层系统是SE Linux,而这里只是实现了“安全上下文”的想法(尽管在Java中),无法提供;这就像尝试将一个包添加到我们说的 RedHat 存储库中,即使能够上传它,它也会失败,而没有使用预期的密钥将其删除。因此,唯一的方法是使用预安装的设备,其中可以定义预期的密钥,就像自己的发行版一样。

以上是关于从应用程序内运行仪器测试并等待结果的主要内容,如果未能解决你的问题,请参考以下文章

命令行窗口内,如何执行一个程序并等待结果

尝试对 Xamarin 应用程序运行 calabash-ios 测试时来自仪器的“无法解释路径(空)”

如何在执行仪器测试期间关闭任何系统对话框

在构建机器上从命令行运行 IOS 仪器的问题

Android Studio导入现有单元测试“无法找到仪器信息”

当状态为“等待审核”时,我可以测试应用内购买吗?