简体   繁体   中英

Execute instrumented test from app in Android

First of all sorry if my question is ignorant, I'm not an Android developer. I have to build a bot application (automatically executes actions in another app) and found out that this is possible with UIAutomator . (I know I'm misusing the framework, but the way I see it what I'm trying to achieve is not possible in any other way.)

I started to build the app and it works, however, I would like to be able to run it without the device being connected to Android Studio. Is it possible to execute the tests from the app by pressing a button or something?

UIautomation relies on android.app.Instumentation which can only be started through adb or from within a System App . For security reasons the system doesn't grant permissions to "execute actions on other apps" unless accesibility permissions has been granted explicitly from the user.

For this reasons I'm afraid it will NOT be possible to use UIAutomator without "being connected to android studio" (this connection is achieved precisely by means of adb, which Android studio uses to connect to the cellphone). You can also use adb directly if needed BUT connection to a computer and adb executable are essential.

More information about UIAutomator and AccessibilityService diferencies here .

Update: Even if it's not possible to use UIAutomator without an adb connection, you can still write your own accessibility service using this detailed guide . Please note it will not allow you to "execute instrumented tests" but to "perform actions in another app".

Do you have to run it in a certain device/through app? What I would do (and this will take a day or two (even more if you are not familiar with it but there are lots of good medium posts etc for doing it)) would be to setup a CI env like Jenkins and either trigger the Jenkins Job whenever I want, or introduce periodic jobs which gets executed in every X hour.

If you are dead set on running it from your phone, good thing here is that you can setup a webhook and trigger it through your app then jenkins will trigger the job you want.

Another plus of this approach is that, theoretically you can scale it to infinity and your bot runs the tests in parallel in X different devices

Once you have setup Jenkins and download Android commandline tools, you will need to create a job, where you build a normal apk and a test apk and install it to the target device.

Here is a small example of build commands you need to provide to run the ui tests (you can either use Emulator Plugin or download your own emulator with avd connect a real device from Firebase Test Labs etc. It also includes the way to disable lock screen/animations which breaks ui tests. Unfortunately whole setup of Jenkins/Android commandline tools far exceeds the scope of this question Here are some helpful content about this

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

Yes its possible.

It can be acheived in two ways:

  • Implement intent based framework in first app and sends customized intents from your second app bundling them with data that can be understood by the first app or from adb

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

  • Implement a TCP server using JAVA socket communication and UiAutomator framework which recognizes and perform operations on UI objects of first app and compile it as Instrument test apk and send comands to this server app from your second app to control it(so 3 apps in total: first, second(client) and server)

I know it sounds confusing at first but yeah it works !!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM