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

21
我正在开发一种QA自动化解决方案,可以在Android上记录/回放QA测试。一个关键的业务需求是在播放记录的测试时不依赖连接的电脑。为此,我正在尝试在没有连接PC的情况下运行一个Instrumentation测试(具体来说,是一个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);

    } 
}

1
你想要等待每个测试的通过或失败结果吗? - Jitesh Mohite
1
我尝试模仿Appium并运行一个测试服务器,直到我杀死它。 - Maor Hadad
1
为什么你不在应用程序中使用“adb shell am instrument -w”? - Jitesh Mohite
1
你不能从应用程序启动adb shell命令。Google已经阻止了它,它将不再起作用。 - Maor Hadad
1
@MaorHadad,你有想到一种实现这个的方法吗? - BruceWayne
显示剩余16条评论
1个回答

1

请参见签名保护级别-澄清...除非将包白名单列入Google的发布密钥,否则无法获取必要的权限。这是一个安全/完整性功能,目的是限制恶意软件能够执行的操作 - 而您打算执行的操作是典型的恶意软件行为 - 无论其实际意图如何;反对系统是没有好处的。

我能想到的唯一方法是直接从终端模拟器或测试应用程序中运行命令,针对定制版AOSP,这样您就可以将android:protectionLevel="signature"添加到Manifest.xml中,然后要求android.permission.INTERACT_ACROSS_USERS_FULL。但对于原始ROM,肯定没有机会这样做。并不是说这是“不可能”的,但构建自定义ROM需要相当大的努力才能达到目标。至少对于NexusPixel设备,所需驱动程序在此here可用;对于其他设备,如果有的话,您必须在设备供应商处找到它们。

关键在于使用与应用程序相同的密钥对ROM进行签名-只有这样才能获得“签名级”权限-而对于原始ROM,理论上需要Google的发布密钥来签署该包。如此处所述,可以强制执行单用户,但这也仅适用于系统应用程序。

我的使用案例(和赏金)是创建可访问性友好的应用程序,以驱动其他应用程序。例如-我可以为残疾人记录某些困难的操作,然后他们会播放它们。虽然这可能被认为是有问题的,但这正是可访问性API应该让我做的事情(用户可以选择加入)。事实上,您可以开始测试,但只是不能等待它,这表明这并不是太难。无论如何,要求用户选择加入没有问题,但让他们安装另一个ROM就不切实际了。 - Benjamin Gruenbaum
1
@BenjaminGruenbaum,赏金并不改变技术要求,这些要求由Android OS定义 - 我已经详细解释过了。如果这是实际可行的,或者适用的,这不是问题的一部分。对我来说,整个概念似乎不现实 - 因为它忽略了现实情况。使用运行Android模拟器的x86平板电脑可能是记录交互的唯一替代方法。 - Martin Zeitler
1
我来澄清一下。启动UIAutomator2不会增加或减少Android或OP应用程序的任何功能。 OP已经使用AccessibilityService,虽然需要权限,但从技术上讲,它可以做到(几乎)所有UIAutomator2可以做到的事情。也就是说,可以在已经使用的API和权限之上重写所有这些代码,但那将是巨大的时间浪费。因此,这肯定不与可能性相矛盾。 - Benjamin Gruenbaum
@BenjaminGruenbaum 错误信息应该类似于java.lang.SecurityException:Permission Denial:get/set设置用户请求以用户-2身份运行,但从用户0调用。 对于任何包,这是不允许的,同时它无法获得那些“签名”级别的权限,这些权限只能由包签名获得。 为了成为操作系统,需要拥有操作系统的签名密钥。 - Martin Zeitler
自从Android 5.0以来,底层系统是SE Linux,而这里仅仅实现了一个“安全上下文”的想法(尽管是在Java中),这是无法提供的;这就像试图将一个软件包添加到RedHat存储库中一样,即使能够上传它,但如果没有使用预期的密钥签名,则也会失败。因此,唯一的方法是使用预安装设备,在其中可以定义期望的密钥,就像拥有自己的发行版一样。 - Martin Zeitler
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接