在 Android 中从应用程序执行插桩测试

Execute instrumented test from app in Android

首先抱歉,如果我的问题很无知,我不是 Android 开发人员。我必须构建一个机器人应用程序(在另一个应用程序中自动执行操作)并发现 UIAutomator 可以做到这一点。 (我知道我在滥用该框架,但我看到它的方式无法以任何其他方式实现我想要实现的目标。)

我开始构建该应用程序并且它可以运行,但是,我希望能够在设备未连接到 Android Studio 的情况下 运行 它。 是否可以通过按按钮或其他方式从应用程序执行测试?

有可能。

可以通过两种方式实现:

  • 在第一个应用程序中实施基于意图的框架,并从您的第二个应用程序发送自定义意图,将它们与第一个应用程序或 adb 可以理解的数据捆绑在一起

    am broadcast -a com.android.example --es KEY some_key --es VALUE some_value

  • 使用 JAVA 套接字通信和 UiAutomator 框架实现 TCP 服务器,该框架识别并执行对第一个应用程序的 UI 对象的操作,并将其编译为 Instrument 测试 apk 并发送命令从你的第二个应用程序到这个服务器应用程序来控制它(所以总共 3 个应用程序:第一个,第二个(客户端)和服务器)

我知道一开始听起来很混乱,但确实有效!!

UIautomation 依赖于 android.app.Instumentation,其中 can only be started through adb or from within a System App。出于安全原因,系统不会授予“在其他应用程序上执行操作”的权限,除非用户明确授予了可访问性权限。

出于这个原因,恐怕如果不“连接到 android studio”就无法使用 UIAutomator(此连接是通过 adb 实现的,Android studio用于连接手机)。如果需要,您也可以直接使用 adb,但连接到计算机和 adb 可执行文件是必不可少的。

有关 UIAutomator 和 AccessibilityService 差异的详细信息

更新: 即使在没有 adb 连接的情况下无法使用 UIAutomator,您仍然可以使用 this detailed guide 编写自己的无障碍服务。请注意,它不允许您“执行插桩测试”,而是“在另一个应用程序中执行操作”。

您是否必须在某个 device/through 应用程序中 运行 它?我会做什么(这将花费一两天时间(如果你不熟悉它甚至更多,但有很多好的媒体帖子等可以这样做))将设置一个 CI 环境,比如 Jenkins 并在我需要时触发 Jenkins Job,或者引入每隔 X 小时执行一次的周期性作业。

如果您对 运行 从您的 phone 进行固定,这里的好处是您可以设置一个 webhook 并通过您的应用程序触发它,然后 jenkins 将触发您想要的工作.

这种方法的另一个优点是,从理论上讲,您可以将其扩展到无穷大,并且您的机器人 运行 可以在 X 种不同的设备上并行进行测试

一旦你设置了 Jenkins 并下载了 Android 命令行工具,你将需要创建一个作业,在那里你 build 一个普通的 apk 和一个测试 apk 并将其安装到目标设备。

这是您需要提供给 运行 ui 测试的 build 命令的一个小示例(您可以使用 Emulator Plugin 或下载您自己的带有 avd 的模拟器连接来自 Firebase 测试实验室等的真实设备。它还包括禁用锁定 screen/animations 的方法,这会破坏 ui 测试。不幸的是,Jenkins/Android 命令行工具的整个设置远远超出了范围这个问题的 这里有一些有用的内容

Setup Jenkins on Ubuntu Setup Android on Jenkins

./gradlew clean myapp:assembleDebug --no-daemon -Dkotlin.compiler.execution.strategy="in-process"
./gradlew myapp:assembleDebugAndroidTest --no-daemon -Dkotlin.compiler.execution.strategy="in-process"


/var/lib/jenkins/android-sdk/platform-tools/adb -s emulator-5558 install -r  myapp/build/outputs/apk/debug/myapp-debug.apk
/var/lib/jenkins/android-sdk/platform-tools/adb -s emulator-5558 install -r -t myapp/build/outputs/apk/androidTest/debug/myapp-debug-androidTest.apk
/var/lib/jenkins/android-sdk/platform-tools/adb -s emulator-5558 shell input keyevent KEYCODE_MENU 
 /var/lib/jenkins/android-sdk/platform-tools/adb -s emulator-5558 shell settings put global window_animation_scale 0 &
    /var/lib/jenkins/android-sdk/platform-tools/adb -s emulator-5558 shell settings put global transition_animation_scale 0 &
    /var/lib/jenkins/android-sdk/platform-tools/adb -s emulator-5558 shell settings put global animator_duration_scale 0 &
   /var/lib/jenkins/android-sdk/platform-tools/adb -s emulator-5558  shell am instrument -w  -e clearPackageData true --no-window-animation  -e package com.mypackage.testcases.tests -e debug false com.mypackage.test/androidx.test.runner.AndroidJUnitRunner