I have created Android unit tests project. They need ADB running for the tests to run successfully.
I have also used the command line tool of Android Debug Bridge for unit testing the Android Unit tests projects.
In above both the cases ADB needs to be running.
Is it possible to run the tests without running ADB. This will be useful for build systems.
If you want to get the errors then you have to use ADB to get the errors.
Related
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.
Currently I use UIAutomator to perform Android UI testing. Basically, I write Java code, compile it, install the jar, and run.
Suppose the UI test app (read UI operations from xml file) is called AppTester.jar, which is used to test the developed app, called myApp.apk. Then I have to run:
adb shell uiautomator runtest AppTester.jar -c com.uia.example.my.AppTester
Therefore, all tests are done on device, not from terminal, after running adb command.
Now I want to use AndroidViewClient for view comparison somewhere in my existing tests. In order to integrate AndroidViewClient into the existing testing framework, it would be ideal if I could run the script (generated by culebra) even the culebra tool that generates the script in my AppTester.jar program.
Is it possible to do that?
uiautomator tests must be run from adb, so you won't get rid of it.
Then you still need your computer to run the tests so it would not be a big difference to run AndroidViewClient/culebra generated tests on the device when you still need adb to run the other tests.
Having said that, perhaps there's a way using SL4A although, I haven't tried it.
As AndroidViewClient/culebra tests are entirely in python and they depend on very few modules perhaps there's a chance.
Next tool generation, which is called Culebra Tester (under private beta now) has the same abilities of culebra but additionally can generate not only python but also Java so you will have no problem unifying your tests.
It runs completely on the device, so the only external requirement is a browser.
The demonstration video shows the generation of a simple UiAutomator test.
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
I developed for my application a small suite of Android tests written in Scala that uses the Robotium library. The suite is for all intents and purposes a standard Android JUnit test project and runs successfully if launched from Eclipse.
I've already successfully built and run my main Android application with sbt android-plugin. The main application is located in [ProjectDir]/src/main. I was also able to successfully build my Android test application that is located in the [ProjectDir]/tests/src/main directory. I checked the emulator, and the test application appears to have been correctly installed with android-plugin's tests/android:install-emulator command. However, when I try to run the test project via sbt tests/android:test-emulator, I get:
...
Test results for InstrumentationTestRunner=
Time: 0.001
OK (0 tests)
How I can get sbt android-plugin to recognize that the project contains JUnit tests and run them?
The naming convention used here is the same as the normal JUnit and as such you need to name the tests xxxTest.class. They also need to extend TestCase (AndroidTestCase, InstrumentationTestCase etc...).
To reiterate, eclipse will run a command which will look like:
adb shell am instrument -w -e class com.android.foo.FooTest,com.android.foo.TooTest com.android.foo/android.test.InstrumentationTestRunner
It will append the classes name to the command so naming convention might not apply.
If you run from sbt, it will run
adb shell am instrument -w com.android.foo/android.test.InstrumentationTestRunner
which will find all the classes under the package name of the application com.android.foo which finishes with someClassNameTest.
What I want my Perl script to do is..
Run the specific Junit test cases from windows command line.
Uninstall the Apk file from android device or emulator.
I am having difficulty in getting started with 1.For step2 , I guess I can use
adb uninstall package name
Thanks.
You don't have to launch eclipse to run junit test cases.
Try running the Junit tests through script using command line.
More information here. http://www.jsystemtest.org/?q=node/44