Run connectedAndroidTest and skip uninstall - android

Is there a way to call the task connectedAndroidTest and skip the uninstall task at the end of the process ?
At the end of the test execution, the app is uninstalled from the device, but I would like to keep the app on the device.
from http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Running-tests :
As mentioned previously, checks requiring a connected device are launched with the anchor task called connectedCheck. This depends on the task connectedDebugAndroidTest and therefore will run it. This task does the following:
Ensure the app and the test app are built (depending on assembleDebug and assembleDebugAndroidTest).
Install both apps.
Run the tests.
Uninstall both apps.

Looking at the sorce of gradle plugin there is no way to prevent uninstalling app at the end of test task. You can check that in SimpleTestCallable class of android gradle plugin.
From what i see there are two options to acchive what you want.
First one is to reinstall app after your connected check is done. Command to do that would look something like this. ./gradlew connectedCheck installDebug installDebugAndroidTest This will execute test on device and delete apps from it. But after that it will reinstall app and test app. So app will still be removed and then installed which means a bit of owerhead but at least apps will not be recompiled twice since you are executing in same gradle execution.
Second option is to not use gradle for executing tests but use adb instead.
To do this you first need to install app and test app through gradle.
./gradlew installDebug installDebugAndroidTest
After that you can execute tests through adb. by caling adb shell am instrument -w com.example.test/android.support.test.runner.AndroidJUnitRunner.
When this is done you can run your cli tests since both app and test app are still installed.
With second approach you would lose all the benefits of executing test wit gradle. Such as code coverage and executing in multiple proceses, etc.

Related

Skipping failed external commands before running app in Android Studio's run config

I want to perform a few cleaning tasks before running my app on Avd, using Android Studio.
I created a configuration that calls adb shell commands like uninstall or rm -r before installing app on emulator.
The problem is that if the app is already uninstalled, then the entire config fails, and the app is not installed.
Is there a way to continue even when previous commands failed?

connectedAndroidTest fails with "no connected devices" but am instrument works

I'm setting up a Jenkins node (on Mac OS X) running instrumentation tests for my Android app.
My Jenkins project starts an Android emulator and runs the Gradle task :app:connectedAndroidTest. But the task has always been unstable, sometimes being able to run the tests just fine, but most of the times failing with the following error:
:app:connectedAndroidTest FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:connectedAndroidTest'.
> com.android.builder.testing.api.DeviceException: No connected devices!
After some investigation, I found that:
The issue only occurs on that machine; on my machine (another Mac OS X), the task has always worked as expected, inside and outside Android Studio;
The issue occurs outside Jenkins, i.e. by manually starting the emulator and running the Gradle task from the command line;
Even though the Jenkins output warned about using nonstandard ports, the issue occurs even when using the more usual 5554-5555;
adb devices shows the emulator in online state;
adb shell am instrument works fine too;
Therefore I can say that the problem is that :app:connectedAndroidTest doesn't detect the running emulator.
I already half-made a shell script that installs the APKs and runs am instrument, but the latter doesn't produce a JUnit-compatible output.
So before doing additional work, I wonder how can I "repair" that Gradle task so that it detects the emulator.
I'm also happy to get advice to further pinpoint the problem, e.g. to find out why the Gradle task works on my machine.
firstly clean your project,and than recreate an Android emulator,execute a cmd commond adb start-service .if fail again you should to use other's emulator in markets.
I'm facing the exact same problem.
Any hint so far? In my former ant script, to ensure adb was connected to the device, we used to to do:
%ANDROID_SDK%-current\platform-tools\adb.exe devices
%ANDROID_SDK%-current\platform-tools\adb.exe root
%ANDROID_SDK%-current\platform-tools\adb.exe devices
%ANDROID_SDK%-current\platform-tools\adb.exe wait-for-device
This way we ensured the device would be available while testing.

connectedAndroidTest on multiple emulators

Background
I want to run my Android Instrumented tests on Jenkins on different emulators. Say I have 100 tests and 4 emulators, I want to run 25 tests on each.
I perform ./gradlew connectedDebugAndroidTest in Jenkins Pipeline's parallel for 4 emulators
stage('Instrumented Tests') {
parallel(
emu1: {
runInstrumentedTestOnEmu(...)
},
emu2: {
runInstrumentedTestOnEmu(...)
}
...
)
}
connectedDebugAndroidTest will spawn other commands in order to setup the environment for running instrumented tests.
...
:app:transformNativeLibsWithMergeJniLibsForDebugAndroidTest
:app:processDebugAndroidTestJavaRes NO-SOURCE
:app:transformResourcesWithMergeJavaResForDebugAndroidTest
:app:validateSigningDebugAndroidTest
:app:packageDebugAndroidTest
:app:assembleDebugAndroidTest
:app:connectedDebugAndroidTest
And when environment is ready then it performes :app:connectedDebugAndroidTest which will start running tests on emulator.
I do not want to run these procedure for all my parallel calls (in this case it would be 4 of them), because obviously I'm doing the exact same job multiple times. Theoretically, the best option would be to perform setup before parallel and when everything is ready for running tests, then go into parallel step and start tests on each emulator.
Question
Is it possible to perform all the pre-setup steps of connectedDebugAndroidTest without performing itself?
Additionally, if I run connectedDebugAndroidTest parallel on 4 emulators the build crashes, because gradle tries to read a file from intermediate directory, when other parallel build has already removed that file, which results in crash.
You can view this test project in github with setup mentioned above.
Is it possible to perform all the pre-setup steps of connectedDebugAndroidTest without performing itself?
Yes, you can run assembleDebugAndroidTest, which as your build log shows, is the last prerequisite to running the device tests. Running that will build both the app and test APKs.
Though AFAIK, there isn't a way of sharding your tests across multiple emulators when using Gradle — you would have to install both of the APKs onto each emulator and use adb shell am instrument with the numShards and shardIndex options.

Android Unit Test Cache

I'm facing an issue whereby whenever I use adb command to run my android test case but it keeps a cache of the last test class. This is even though I have changed my code and rebuild.
I'm running below command
./adb shell am instrument -w -e class com.xxx.yyy.tests/SignInActivityTest com.xxx.yyy.test/android.test.InstrumentationTestRunner
I add some test method, it is still caching and run the old test case.
If you are using command line; Make sure to re-build the test application and not only the application under test and that both are deployed to the target before running tests again.

Android CI with Atlassian Bamboo

Does anyone have any good resources for setting up Bamboo to do CI with Android projects? I have mine setup to pull source and compile it with ant. But I would love to know how to setup JUnit tests, where the tests are in a separate project.
Thanks
I have figured out how to do it using Bamboo CI and new Android Studio projects with gradle. Bamboo does not have nice drop in tasks yet but you can leverage the script runner to do it. We setup our basic build tasks as follows:
Source Code Checkout.
Script task:
Script Location: Inline
Script Body: gradlew.bat assembleDebug test (our Bamboo server is Windows so we use the bat file, linux use the ./gradlew assembleDebug test command)
Then we add a final task of JUnit parser, and we use the result directory line of: **/test-results/debug/*.xml
As for testing we use Robolectric Gradle tests, which generate JUnit test results.
I hope this helps anyone else who is looking into how to setup Bamboo with Android, hopefully they will add support one day like they do for .NET where its just a single task that builds and tests. The script command feels kind of a hack.
If someone is looking for Ant style tests, I can share that too but hopefully by now everyone has moved to Android Studio from eclipse. I will say the steps required for Ant and Instrumentation take a lot more time to setup and I had to use an emulator running on the server to do the tests.
In addition to using Bamboo to build the APK for my Android project, I also wanted to use Bamboo to run the JUnit based tests against an Android emulator. After quite a bit of "trial and error" primarily around finding a reliable way to start and stop the Android emulator, here is what I came up with for my Bamboo build plan. See Bamboo waits for script task to terminate, although it is run in the background for additional background information regarding why I take the approach described below.
My Bamboo plan has one stage with two jobs. The jobs run using two agents that execute on the same system. Both jobs start and run in parallel. One job starts the Android emulator using the Android SDK emulator command. The other job waits for the emulator to start, builds the mobile app, runs the tests against the emulator and then stops the running emulator using a final task that is always executed even if a previous task in the build job fails.
The emulator job does get "stuck" after starting the emulator because it is waiting for the emulator process to finish. When the build job runs, the final task in the build job stops the emulator which causes the emulator job to finish because the emulator process is no longer running.
Here are the key task details for the build job:
First task is a script task that waits for the emulator to start. The adb -s command below will fail causing this task to fail if the emulator failed to start.
echo "Waiting 60 seconds for the Android emulator to start"
sleep 60
echo "See if Emulator is up and running"
${bamboo.ANDROID_HOME}/platform-tools/adb -s emulator-5554 shell getprop dev.bootcomplete
The second and third tasks check out the source and build the app using Gradle. The build runs the JUnit tests against the running emulator.
The fourth task which is configured as a final task is a script task that stops the emulator.
echo "Stopping the Android emulator"
${bamboo.ANDROID_HOME}/platform-tools/adb -s emulator-5554 emu kill

Categories

Resources