I am unable to run instrumentation tests in my Android project in two cases:
When running individual tests (i.e. a single #Test)
When running all tests in a class
I am able to run instrumentation tests by right clicking on the folder the test is in and selecting the Run 'Tests in PACKAGE_NAME' option
Here's an example of running an individual test:
Testing started at 6:35 PM ...
12/30 18:35:05: Launching getId()
$ adb push /Users/zach/Developer/Code/testapp/app/build/outputs/apk/develop/debug/app-develop-debug.apk /data/local/tmp/com.zao.testapp.develop
$ adb shell pm install -t -r "/data/local/tmp/com.zao.testapp.develop"
Success
APK installed in 4 s 42 ms
No apk changes detected since last installation, skipping installation of /Users/zach/Developer/Code/testapp/app/build/outputs/apk/androidTest/develop/debug/app-develop-debug-androidTest.apk
Running tests
$ adb shell am instrument -w -r -e debug false -e class 'com.zao.testapp.models.entities.impl.EntityParseTest#getId' com.zao.testapp.develop.test/com.zao.testapp.TestRunner
Client not ready yet..
Started running tests
Test running failed: Fatal exception when running tests
java.lang.IllegalArgumentException: Ambiguous arguments: cannot provide both test package and test class(es) to run
at android.support.test.internal.runner.TestRequestBuilder.validate(TestRequestBuilder.java:773)
at android.support.test.internal.runner.TestRequestBuilder.build(TestRequestBuilder.java:742)
at android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:354)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:260)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2075)
Empty test suite.
And when I run via the right click option to run all tests in the package, here is what I see:
Testing started at 6:40 PM ...
12/30 18:40:38: Launching Tests in 'com.zao.testapp.models.entities.impl'
$ adb push /Users/zach/Developer/Code/testapp/app/build/outputs/apk/develop/debug/app-develop-debug.apk /data/local/tmp/com.zao.testapp.develop
$ adb shell pm install -t -r "/data/local/tmp/com.zao.testapp.develop"
Success
APK installed in 4 s 471 ms
No apk changes detected since last installation, skipping installation of /Users/zach/Developer/Code/testapp/app/build/outputs/apk/androidTest/develop/debug/app-develop-debug-androidTest.apk
Running tests
$ adb shell am instrument -w -r -e package com.zao.testapp.models.entities.impl -e debug false com.zao.testapp.develop.test/com.zao.testapp.TestRunner
Client not ready yet..
Started running tests
Tests ran to completion.
The only "gotcha" here might be that I am using a custom test runner (TestRunner.java that is referenced above). I'm not sure that matters too much though. I'll try removing this (some of the tests need the custom runner, but I can disable those for now...)
Any thoughts? Thanks!
I debugged this issue and figured out the root cause. I was using a custom runner that was ignoring a package from being tested. I implemented a workaround described in https://github.com/mockito/mockito/issues/922 to get my mockito stuff working with the custom runner, and this resulted in the error.
Putting arguments.putString("notPackage", "net.bytebuddy"); in the runner's onCreate resulted in TestRequestBuilder.java throwing an exception in the validate method, which does this:
if ((!mIncludedPackages.isEmpty() || !mExcludedPackages.isEmpty()) && !classNames.isEmpty()) {
throw new IllegalArgumentException(AMBIGUOUS_ARGUMENTS_MSG);
}
Where mExcludedPackages has a size of 1 (net.bytebuddy), while classNames is also not empty and contains the class I am running tests in.
Therefore to fix this you can either do one of two things:
Remove the arguments.putString("notPackage", "net.bytebuddy") workaround (which makes mockito not work in some cases for my tests).
Refactor your tests to not need the custom runner, thereby doing step 1 as well.
Not be able to run tests for specific tests/files.
I ended up doing step 2, FWIW.
Related
I have a strange situation with Jenkins when trying to run the tests.
The configuration of the job clearly specifies to run the tests on this specific avd: "hudson_en-US_160_HVGA_android-18_armeabi-v7a", but for some odd reasons, during the build process, 2 devices are found. One of the devices is the previous one, but the other is called "unknown-sdk".
The tests are successfully executed on the specific avd, and fail on "unknown-sdk":
The relevant portion of the log:
[SR.runTests] Executing instrumentation suite on 2
device(s).
[SR.runTests] [emulator-8215] Starting
execution.
[SR.runTests] [localhost:8216] Starting
execution.
Running am instrument -w -r -e class com.smoke.tests.LoginTest
com.muume.dev.test/android.support.test.runner.AndroidJUnitRunner on
unknown-sdk-localhost:8216
2015-06-17 11:54:05 [SDR.printStream] [localhost:8216] STDOUT 11:54:05
I/InstrumentationResultParser: test run failed: 'Unable to find
instrumentation info for:
ComponentInfo{com.muume.dev.test/android.support.test.runner.AndroidJUnitRunner}
As you can see, it detected 2 devices: emulator-8215 which is the known avd, and localhost-8216 which is the unknown and causes the problems.
My question is how to restrict the tests to run only one single emulator, and from where did the "unknown-sdk-localhost" comes from.
"unknown-sdk" is what it tells adb while the emulator is still busy loading itself.
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.
We have a library project and multiple applications depends on it. And the unit tests are in the library project.
We're able to run the tests from dependent projects in Android Studio, but
./gradlew :[DependentProject]:connectedAndroidTest
always returns "No test found, nothing to do”.
Through observation, I found in Android Studio, seems that it only executes gradle tasks:
:[DependentProject]:assembleDebug, :[DependentProject]assembleDebugTest
then uses adb to install the target and test apk, and adb shell am instruments to run the tests.
Since connectedAndroidTest depends on these two tasks, I install the target and test apks it produced, and manually invoked instrument command, tests got started.
adb shell am instrument -w com.package.test/android.test.InstrumentationTestRunner
Then the question comes, where does connectedAndroidTest look for tests, and why it cannot find the tests while adb instrument can? How to resolve this issue?
I have the same issue and I solve it by add a method starting with "test"
#Test
public void testWTF() throws Exception {
assertTrue(true);
}
And all other method with #Test annotation work too !
Amazing no ? I found the answer here : No tests found with test runner 'JUnit 4'
I want to install android app from local driver on emulator and run tests of espresso on already existing app. Is there any way to skip installation of app in espresso tests?
You could install your apks using ADB and then start the tests manually:
$ adb install myapp.apk (1)
$ adb install myapp-androidTest-unaligned.apk (2)
$ adb shell am instrument -w com.myapp.test/android.support.test.runner.AndroidJUnitRunner (3)
(1) upload your app apk
(2) upload your test apk apk
(3) be sure to use your test apk's package name which is usually your app package name, post-fixed with .test. Also you have to use the fully qualified test runner. This is whatever you specified as the testInstrumentationRunner in your build.gradle file.
To answer your question, you may not need to do steps 1 and 2 if the apk and test apk are already on your device (perhaps by previously running ./gradlew connectedAndroidTest)
Have a look in this Android doc page, it tells a little bit more about the adb shell am instrument commend.
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.