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
Related
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?
As the title says, Jenkins can correctly switch directories to the adb and then execute it. But it can not use it when it is outside of adb's directory.
The following code :
.//opt/android-sdk-linux//platform-tools/adb --help
results in the following output :
+ .//opt/android-sdk-linux//platform-tools/adb
/tmp/jenkins882020622874679741.sh: rad 18: .//opt/android-sdk-linux//platform-tools/adb: Filen eller katalogen finns inte
Build step 'Execute shell' marked build as failure
Finished: FAILURE
While this code :
cd /opt/android-sdk-linux//platform-tools/
ls
./adb --help
correctly outputs the adb help manual.
Additionally, entering
adb --help
gives the same error even when the path given by "which adb" is appended to the $PATH variable.
ls /opt/android-sdk-linux//platform-tools/adb
also shows that it can see adb from its current directory.
How do I make jenkins run adb without switching directories to the adb directory?
edit 1:
Adding an alias to adb resulted in this error:
+ alias adb=.//opt/android-sdk-linux//platform-tools/adb
+ adb shell am instrument -w -r -e debug false -e class se.***** se.*******/android.support.test.runner.AndroidJUnitRunner
/tmp/jenkins523172794505644997.sh: rad 24: adb: kommandot finns inte
Build step 'Execute shell' marked build as failure
Finished: FAILURE
Clearly, something is still wrong with the PATH inclusion so maybe have Jenkins print the PATH variable to debug. A temporary solution could be using an alias:
$ alias adb=".//opt/android-sdk-linux//platform-tools/adb"
This command will result in .//opt/android-sdk-linux//platform-tools/adb being executed every time you execute adb.
After working for a while on this I found that Jenkins allows you to inject environment variables in the device configuration. You can also inject environment variables for each build separately. I do not know why exporting them through a bash script does not work but this is what worked for me. In summary, injecting the $PATH variable using Jenkins' built in tool fixed everything.
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.
After running ant clean emma debug and installing the generated apk file on my emulator, I am running the following command to run my unit tests:
adb shell am instrument -w -e package org.company.projectname.test.unit -e coverage true \
-e coverageFile ProjectNameTest/bin/coverage.xml org.company.projectname.tests/com.neenbedankt.android.test.InstrumentationTestRunner'
The InstrumentationTestRunner I am using is a subclass of android.test.InstrumentationTestRunner.
When I run this command, all the tests pass, but then no coverage is generated and I get the error:
Error: Failed to generate emma coverage. Is emma jar on classpath?
I am not looking for a solution that uses ant test, unless that solution can address the reason I' not using it, which is that I wanted to be able to specify a package within org.company.projectname.test to test (in this case the unit package).
This worked for me:
ant instrument
ant emma installi test
Edit:
If you do not want to use Ant you have to build the instrumented apk manually, check $ANDROID_HOME/tools/ant/build.xml for more info and make sure emma.jar is under libs of your test project.
Try :
ant all clean emma debug install test
and also please check http://code.google.com/p/android/issues/detail?id=21640 , it seems like this issue is fixed latest commit
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"