I am trying to automate my build and make running our acceptance tests a part of that.
Unfortunately the gradle task connectedAndroidTest is reporting
Starting 0 tests on Nexus_5X_API_25(AVD) - 7.1.1
com.android.builder.testing.ConnectedDevice > No tests found.[Nexus_5X_API_25(AVD) - 7.1.1] FAILED .
No tests found. This usually means that your test classes are not in the form that your test runner expects (e.g. don't inherit from TestCase or lack #Test annotations).
This does not happen when I run the tests/suite from the IDE.
I found that Android Studio is executing following commands:
$ adb push /path/to/apk/app-debug.apk /data/local/tmp/com.MyApp
$ adb shell pm install -r "/data/local/tmp/com.MyApp"
$ adb push /path/to/apk/app-debug-androidTest.apk /data/local/tmp/com.MyApp.test
$ adb shell pm install -r "/data/local/tmp/com.MyApp.test"
$ adb shell am instrument -w -r -e debug false -e class com.myapp.TestSuite com.MyApp.test/com.myapp.testrunners.CreationInterceptingTestRunner
I know what those commands do but I do not know what connectedAndroidTest is doing under the hood and why it fails.
I found out that the issue has to do with multidex. At the end of the official page about enabling multidex it reads:
Notes:
* Don't use MultiDexTestRunner, which is deprecated; use AndroidJUnitRunner instead.
* Using multidex to create a test APK is not currently supported.
I do not understand what is mean with create test APK and why the adb command works.
I do not want to run the adb commands by hand as they have no reporting built in and I would need to do this all myself.
Is there any way to use connectedAndroidTest with multidex apps?
Related
My app is implemented as a multi-module project (with dynamics module), where there is a shared module with espresso tests. These espresso tests give me different outcomes depending if I run them from Android Studio or from the command line.
The issue I find when I run the tests from the command line is that it tries to assert against the wrong string resources.
The actual tests code is asserting this, where R.string.home_activity_title value is "Hello":
assertDisplayed(R.string.home_activity_title)
However when it is run from the command line, the assertion fails with this output
No views in hierarchy found matching: with string from resource id: <2131886676>[send_message_hint] value: Type a messageā¦
Notice how the tests from the command line is trying to assert against a different string that the one is defined on the test.
I tried to understand the difference between running the tests from AndroidStudio and running them from the command line but I am clearly missing something here. This is how I run the tests from the command line
apk="path/to/apk"
testApk="path/to/test/apk"
testRunner="my.custom.test.runner"
# Generate universal APK
echo "Generating universal APK"
sh build_develop.sh
# Install universal APK on emulator
echo "Installing universal APK"
adb uninstall <appPackage>
adb install -t $apk
echo "Building test APK"
./gradlew :testModule:assembleDebugAndroidTest
echo "Installing Test APK"
adb uninstall <testApkPackage>
adb install -t $testApk
echo "Running Acceptance Tests"
# Run all acceptance tests
adb shell am instrument -w $testRunner
Try specifying the module for which you want the string to be obtained.
E.g. com.example.module.R.string.home_activity_title instead of R.string.home_activity_title
I am using both frameworks to test my application.
I know these commands to run each:
Instrumentaion: gradlew clean connectedAndroidTest
Robolectric : gradlew clean build
I have tried others, but these are the points in my opinion.
Are there any command to run both tests?
You can use this command to run all tests:
adb shell am instrument -w com.android.foo/android.test.InstrumentationTestRunner
Or this to run single testcase:
adb shell am instrument -w -e class com.android.foo.FooTest com.android.foo/android.test.InstrumentationTestRunner
More info how to use here: link
Here is example how I'm using this command
adb shell am instrument -w -e class app.name.androidTest.TestCustomer mobile.touch.core.test/android.test.InstrumentationTestRunner
It's great becouse it runs test immediately
Another way is implementing spoon-gradle-plugin Spoon plugin is great for running test and generating reports.
Command to run test with spoon:
gradle spoon -PspoonClassName=fully.qualified.TestCase
When I run instrumentation tests from within Android Studio, I see that the app remains on the device afterwards. But I can't figure out to do this from the command line with gradlew. My intention is to run tests that save screenshots in e.g /data/data/MyApp/cache/screenshots and download these with adb pull afterwards.
./gradlew connectedAndroidTest
causes the app to be uninstalled. I also tried
./gradlew connectedAndroidTest -x uninstallAndroidTest
but that didn't make any difference. What's causing the uninstallation, and how can I avoid it?
I solved this by letting gradle only build the apk, and then handling the install/test/uninstall work with adb. Here's an approximation of my script.
PKGNAME=com.corp.app
./gradlew assembleAndroidTest
adb install -r app/build/outputs/apk/app-debug.apk
adb install -r app/build/outputs/apk/app-debug-androidTest-unaligned.apk
adb shell am instrument -w ${PKGNAME}.test/android.support.test.runner.AndroidJUnitRunner
[ -d screenshots ] || mkdir screenshots
adb pull /data/data/${PKGNAME}/cache/screenshots screenshots
# Now we can uninstall.
adb uninstall ${PKGNAME}.test
adb uninstall ${PKGNAME}
I didn't find the way out of this problem. Looks like there is no way to run instrumentation test without uninstalling. You can use gradle commands to build and install your app and testApp. It is a better way to use these commamds because apps will be installed on all connected devices.
gradlew installVersionDebug
gradlew installVersionDebugAndroidTest
adb shell am instrument -w -r -e debug false -e class com.example.android.EspressoUITest {PKGNAME}.test/android.support.test.runner.AndroidJUnitRunner
But there is still a problem with reports. You can use custom testRunner to generate a JUnit style XML report. Such report could be converted to HTML format with common approach.
I have a simple android app and I am testing it using my phone. So, there are two ways to do that :
Using eclipse
Using CLI
Problem:
When I run unit test case using Eclipse, it installs app on my phone at runtime and run junit test and after that if I use command on CLI:
adb -d shell am instrument -w com.abc.xyz.test/android.test.InstrumentationTestRunner, it runs fine.
However, if I directly run the above command in CLI without first running the unit test cases in Eclipse, I am getting error:
android.util.AndroidException: INSTRUMENTATION_FAILED: com.abc.xyz.test/android.test.InstrumentationTestRunner
at com.android.commands.am.Am.runInstrument(Am.java:586)
at com.android.commands.am.Am.run(Am.java:117)
at com.android.commands.am.Am.main(Am.java:80)
at com.android.internal.os.RuntimeInit.finishInit(Native Method)
at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:263)
at dalvik.system.NativeStart.main(Native Method)
INSTRUMENTATION_STATUS: id=ActivityManagerService
INSTRUMENTATION_STATUS: Error=Unable to find instrumentation target package: com.abc.xyz
INSTRUMENTATION_STATUS_CODE: -1
AndroidMAnifest.xml contains:
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.abc.xyz"
inside instrumentation tag
Could anyone please help me
I suppose that you will have solved it since january, but I work with command-line tools, found similar problem (error message is different) and solved it like I explain in following steps. I do the whole process from creating a dummy project with its empty test until a successful test run. I hope it can be useful for someone:
First step, create the project:
android create project
--name MyExample
--target "Google Inc.:Google APIs:17"
--path MyExample
--package com.example
--activity MyExampleActivity
Second step, create test project:
android create test-project
--path MyExampleTest
--name MyExampleTest
--main ../MyExample
Third step, access to your project directory, build it and check that the process ends successfully:
cd MyExample && ant debug
Fourth step, install it to the emulator:
adb -s emulator-5554 install -r bin/MyExample-debug.apk
Fifth step, access to your test project directory and try to run the tests:
cd ../MyExampleTest &&
adb shell am instrument -w com.example.tests/android.test.InstrumentationTestRunner
That yields:
INSTRUMENTATION_STATUS: id=ActivityManagerService
INSTRUMENTATION_STATUS: Error=Unable to find instrumentation info for: ComponentInfo{com.example.tests/android.test.InstrumentationTestRunner}
INSTRUMENTATION_STATUS_CODE: -1
android.util.AndroidException: INSTRUMENTATION_FAILED: com.example.tests/android.test.InstrumentationTestRunner
at com.android.commands.am.Am.runInstrument(Am.java:676)
at com.android.commands.am.Am.run(Am.java:119)
at com.android.commands.am.Am.main(Am.java:82)
at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:235)
at dalvik.system.NativeStart.main(Native Method)
Sixth step, list your instrumentation clases and ensure that your current project is missing:
adb shell pm list instrumentation
That in my machine yields:
instrumentation:com.android.emulator.connectivity.test/android.test.InstrumentationTestRunner (target=com.android.emulator.connectivity.test)
instrumentation:com.android.emulator.gps.test/android.test.InstrumentationTestRunner (target=com.android.emulator.gps.test)
instrumentation:com.android.example.spinner.tests/android.test.InstrumentationTestRunner (target=com.android.example.spinner)
instrumentation:com.android.smoketest.tests/com.android.smoketest.SmokeTestRunner (target=com.android.smoketest)
instrumentation:com.android.smoketest.tests/android.test.InstrumentationTestRunner (target=com.android.smoketest)
instrumentation:com.example.android.apis/.app.LocalSampleInstrumentation (target=com.example.android.apis)
As you can see, the instrumentation for com.example.tests doesn't exist, so we will have to create it.
Seventh step, build you test project and check that it did successfully:
ant debug
Eigth step, install it to the emulator:
adb -s emulator-5554 install -r bin/MyExampleTest-debug.apk
Ninth step, list your instrumentation classes and look for the one of your project:
adb shell pm list instrumentation
That yields:
instrumentation:com.android.emulator.connectivity.test/android.test.InstrumentationTestRunner (target=com.android.emulator.connectivity.test)
instrumentation:com.android.emulator.gps.test/android.test.InstrumentationTestRunner (target=com.android.emulator.gps.test)
instrumentation:com.android.example.spinner.tests/android.test.InstrumentationTestRunner (target=com.android.example.spinner)
instrumentation:com.android.smoketest.tests/com.android.smoketest.SmokeTestRunner (target=com.android.smoketest)
instrumentation:com.android.smoketest.tests/android.test.InstrumentationTestRunner (target=com.android.smoketest)
instrumentation:com.example.tests/android.test.InstrumentationTestRunner (target=com.example)
instrumentation:com.example.android.apis/.app.LocalSampleInstrumentation (target=com.example.android.apis)
Look at the second to last, instrumentation:com.example.tests, it's which we wanted.
Tenth step, run your tests:
adb shell am instrument -w com.example.tests/android.test.InstrumentationTestRunner
That yields:
Test results for InstrumentationTestRunner=
Time: 0.0
OK (0 tests)
That is all. Now implement your tests, compile and install as usual. Additionally you can remove them like:
adb shell pm uninstall com.example.tests
But you will need to create instrumentation classes again to avoid the same error.
A more precise explanation/approach is the following:
Make sure you do
adb install -r bin/<>-debug.apk
from both from tests and the app directory.
After that ant test should work from the tests directory. (My guess is that there was a missing dependency to the app from test package - which was causing the failure).
Other than the above little hack, rest of the procedure I followed came from the android testing introduction on http://developer.android.com/.
Make sure you uninstall the previous app and reinstall or kick off the test only after uninstalling the previous app
I would like to run monkey on Jenkins but after use configuration:
https://wiki.jenkins-ci.org/pages/viewpage.action?pageId=57181910
I see in monkey.txt file:
No activities found to run, monkey aborted.
$ E:\server\AndroidSDK/platform-tools/adb.exe -s localhost:46881
shell monkey -v -v -p package.name -s 0 --throttle 0 50
$E:\server\AndroidSDK/platform-tools/adb.exe disconnect
localhost:46881 [android] Stopping Android emulator [android]
Archiving emulator log
I run this command on my PC, but I cannot run it on server.
If I run the command: adb shell monkey -v -v 50 -p package.name -s --throttle 0 on cmd on server it will work.
How can I configure Jenkins to run monkey properly?
I'm using the newest plugins for Jenkins.
Are you really using "package.name" in the monkey command line rather than your actual package name?
Did you ensure the APK was installed on the emulator before running monkey?
Otherwise, is there any output in the logcat.txt which indicates what's going wrong?
Also, I'm not sure why you linked to a really old version of the Android Emulator Plugin wiki page, but since then there's a Jenkins build step that will run monkey for you, without you having to manually write it into a batch script step.
Like Thomas pointed out in Christopher's comment:
You also have to think about installing the apk to the smartphone.
This can be done by using the "install android package" build step before "Run android monkey tester".
After that you can add another build step "uninstall android package"