Running android unit tests from the command line? - android

I'm trying to run unit tests on the android platform in accordance with tutorial. Say, for example, I want to run tests for Email application. I open /apps/Email/tests/AndroidManifest.xml file, look for the <manifest> element, and look at the package attribute, which is com.android.email.tests, and in the <instrumentation> element I look at the android:name attribute, which is android.test.InstrumentationTestRunner. Now I open the console, and run
$ . build/envsetup.sh
$ lunch 1
$ adb shell am instrument -w com.android.email.tests/android.test.InstrumentationTestRunner
But that fails:
INSTRUMENTATION_STATUS: id=ActivityManagerService
android.util.AndroidException: INSTRUMENTATION_FAILED: com.android.email.tests/android.test.InstrumentationTestRunner
INSTRUMENTATION_STATUS: Error=Unable to find instrumentation info for: ComponentInfo{com.android.email.tests/android.test.InstrumentationTestRunner}
So.. What am I doing wrong?

Please run
python development/testrunner/runtest.py email
and then you will see it works :).
Basically you do not have com.android.email.tests package installed.
You can see what is available for instrumentation
pm list instrumentation
And you should see
instrumentation:com.android.email.tests/android.test.InstrumentationTestRunner
(target=com.android.email)
And when doing
pm list packages
package:com.android.email
package:com.android.email.tests

You may need to setup a test project with the android create test-project command first. Check this page on the Android Dev site: Testing In Other IDE's for more info. I've used this method to enable command line testing with ant.

What I actually forgot to do was building and installing that test packages onto my device/emulator. Discovered that after doing:
$ adb shell
# cd data/packages
# ls
And no com.android.email.tests package there.

My issue was this tag:
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:label="Tests for app.under.test.package"
android:targetPackage="app.under.test.package" />
Firstly I had the android:name attribute wrong then the target package wrong (above is the correct solution)

Test Package Not Installed on the Emulator
I had the exact same issue and realized that the test package hadn't been installed on the emulator, which is what #marekdef is saying.
Instead of using the command found in the generated test file, I used the following:
ant debug install test
*I had my test project in <project_home>/tests so the following command is what I ended up using from my project home directory:
(cd tests && ant debug install test;)
Hope that helps.

I received the "Unable to find instrumentation info" error under this condition: I defined my test project with a src package name that was the same as that of the project-under-test. For example, the source for both projects was in package com.mycompany.android. This parallel-src-package setup worked fine in Eclipse, but on the emulator it very much appeared that the test apk was overwriting the app apk.
Fix: I changed the src packge of the test project to test.mycompany.android.
Note that, in either case, the Android manifest for the test project defines:
< manifest package="pkg-of-project-under-test" ...>
and
< instrumentation android:targetPackage="pkg-of-project-under-test" ...>

For gradle user you can use the following tasks:
$ gradle :project:installDebug :project:installDebugAndroidTest

I have this run_all_test.sh script to run all unit and instrumented test:
#!/bin/bash
./gradlew --no-daemon clean test connectedCheck --stacktrace;
if [ $? -eq 0 ]
then
echo "tests are successful"
else
echo "tests FAILED"
exit 1
fi
Explanation:
test -> execute all unit test
connectedCheck -> execute all instrumented test
You can start from here to customize it based on your needs following the documentation here: https://developer.android.com/studio/test/command-line

[Android test types]
To run all tests from Command Line using gradlew[About]
JUnit test (UnitTest suffix)
./gradlew test
./gradlew :<moduleName>:test<variantName>UnitTest
Instrument test(AndroidTest suffix)
./gradlew connectedAndroidTest
./gradlew :<moduleName>:connected<variantName>AndroidTest
If you want just to build tests and don't run them use assemble
//Unit
./gradlew :<moduleName>:assemble<variantName>UnitTest
//functional
./gradlew :<moduleName>:assemble<variantName>AndroidTest

Related

how to execute individual Junit test in android using gradle

My project contains multiple test classes and each class contains some test methods.
I can run all the test using command line
gradlew testDebugUnitTest
Is there any gradlew command to run specific testMethod from a class?
Is there any gradlew command to run all test mmethods from a specific class?
Here is a class Foo2 and bar3 is the particular method you would like to test. This was taken from the Google developer Junit unit test command line documentation
$ adb shell am instrument -w \
> -e class com.android.demo.app.tests.Foo2#bar3 \
> com.android.demo.app.tests/android.support.test.runner.AndroidJUnitRunner

Instrumented tests not found with custom instrumentation - conditional instrumentation?

I have a working Android app with a manifest containing this <instrumentation> node
<instrumentation
android:name=".MyInstrumentation"
android:targetPackage="my.package"/>
I have instrumented tests also, but when I run those I get this
$ adb shell am instrument -w -r-e debug false my.package.test/my.package.MyInstrumentation
Client not ready yet..
Started running tests
Test running failed: Unable to find instrumentation info for: ComponentInfo{my.package.test/my.package.MyInstrumentation}android.util.AndroidException: INSTRUMENTATION_FAILED: my.package.test/my.package.MyInstrumentation
. onError: commandError=true message=INSTRUMENTATION_FAILED: my.package.test/my.package.Instrumentation
and tests are not run.
If I remove the instrumentation declaration from the manifest it works fine, when I run the tests like this I get this
$ adb shell am instrument -w -r -e debug false my.package.test/androidx.test.runner.AndroidJUnitRunner
Client not ready yet..
Started running tests
Tests ran to completion.
androidx.test.runner.AndroidJUnitRunner is the instrumentation that gets executed.
This happens when I run the tests from Android Studio and also when I execute ./gradlew connectedAndroidTest.
How can I tell gradle or Android Studio that I want to run the tests with the AndroidJUnitRunner instrumentation? With still allowing my own.
add this line in your build.gradle file, and try
android {
...
defaultConfig {
...
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
...
}
...
}

How to implement code coverage into github android project (Travis CI, codecov)

I am now struggling with adding code coverage to my Android test project, can someone help?
https://github.com/zisean/CarbonContact-SCC-Group1
CI: Travis
You can read the error in this line, a permission denied.
You can fix it adding the next lines to your .travis.yml:
before_install:
- chmod +x gradlew
Alternatively, you can add the exec-permission to your gradlew script via git like this:
git update-index --chmod=+x gradlew

Error building Alljoyn Certification Test 15.09

I'm trying to build the certification apk for Alljoyn 15.09a. I've cloned the source from https://git.allseenalliance.org/gerrit/compliance/tests and followed the instructions from chapter 5 in AllJoyn™ Validation Test User Guide. It has an error in the validation-tests-suites. The error message is:
Failed tests:
ConfigTestSuiteTest.test_26_timedOutWaitingForSessionLost:1511->BaseTestSuiteTest.executeTestMethodFailsAssertion:67 No assertion failure, expecting assertionFailure with message: Timed out waiting for session to be lost
ConfigTestSuiteTest.test_27_configurationNotRetainedOnRestart:1613->BaseTestSuiteTest.executeTestMethodFailsAssertion:73 expected:<[Received About announcement did not contain expected DeviceName expected:<[newD]eviceName> but was:<[d]]eviceName>> but was:<[Value for DeviceName retrieved from GetAboutData() does not match expected value expected:<deviceName> but was:<newD]eviceName>>
ConfigTestSuiteTest.testConfig_v1_33FactoryResetNoUpdateConfiguratins:1752
mockServiceHelper.waitForNextDeviceAnnouncement(
<any>,
<any>,
<any>
);
Wanted 3 times:
-> at org.alljoyn.validation.testing.suites.config.ConfigTestSuiteTest.testConfig_v1_33FactoryResetNoUpdateConfiguratins(ConfigTestSuiteTest.java:1752)
But was 4 times. Undesired invocation:
-> at org.alljoyn.validation.testing.suites.config.ConfigTestSuite.waitForNextDeviceAnnouncement(ConfigTestSuite.java:181)
ConfigTestSuiteTest.testConfig_v1_35FactoryResetResetsPasscode:1830
mockServiceHelper.waitForNextDeviceAnnouncement(
<any>,
<any>,
<any>
);
Wanted 4 times:
-> at org.alljoyn.validation.testing.suites.config.ConfigTestSuiteTest.testConfig_v1_35FactoryResetResetsPasscode(ConfigTestSuiteTest.java:1830)
But was 5 times. Undesired invocation:
-> at org.alljoyn.validation.testing.suites.config.ConfigTestSuite.waitForNextDeviceAnnouncement(ConfigTestSuite.java:181)
ConfigTestSuiteManagerTest.getApplicableTests:86->validateValidationTestGroup:97->validateValidationTestItems:107 expected:<27> but was:<25>
Tests in error:
ConfigTestSuiteTest.test_27_timedOutWaitingForSessionLost:1587->BaseTestSuiteTest.executeTestMethodFailsAssertion:66->executeTestMethod:2394 » NullPointer
Tests run: 674, Failures: 5, Errors: 1, Skipped: 14
I've made sure I have the correct Maven and Java version. I've also tried 14.12 and getting the same issue, so I think my setup is wrong. Can anyone help me with compiling this?
I found the solution. There is another document: AllSeen Alliance Self-Certification User Guide at https://wiki.allseenalliance.org/_media/compliance/allseen_self_certification_program_developer_guide_v5.doc.
It updates the final step to:
$ mvn clean install –Dmaven.test.skip=true -Dandroid.sdk.path=$ANDROID_SDK
which fixed my problem. So the steps I followed were
$ git clone https://git.allseenalliance.org/gerrit/compliance/tests
Copy the libraries listed in the README.txt in $VAL_DIR/java/components/validation-dependencies/libs to $VAL_DIR/java/components/validation-dependencies/libs
$ cd tests/java/components/validation-base/HEAD/
$ mvn clean install
$ cd ../../validation-dependencies/HEAD/
$ mvn clean install
$ cd ../../validation-framework/HEAD/
$ mvn clean install
$ cd ../../validation-tests/HEAD/
$ mvn clean install -Dmaven.test.skip=true -Dandroid.sdk.path=$ANDROID_SDK

Debugging Android NDK native apps

I'm trying to debug and step through an Android application that segfaults. I've tried ndk-gdb, but with little luck. I've also referred to Android NDK Debugging without being able to debug my app.
When I try ndk-gdb --start, and I get:
$ ndk-gdb --start --verbose
Android NDK installation path: /opt/android-ndk-r7
Using default adb command: /opt/android-sdk-linux/platform-tools/adb
ADB version found: Android Debug Bridge version 1.0.29
Using final ADB command: '/opt/android-sdk-linux/platform-tools/adb'
Using auto-detected project path: .
Found package name: com.example.native_plasma
ABIs targetted by application: armeabi armeabi-v7a
Device API Level: 10
Device CPU ABIs: armeabi-v7a armeabi
Compatible device ABI: armeabi-v7a
Found debuggable flag: true
Found device gdbserver: /data/data/com.example.native_plasma/lib/gdbserver
Using gdb setup init: ./libs/armeabi-v7a/gdb.setup
Using toolchain prefix: /opt/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-
Using app out directory: ./obj/local/armeabi-v7a
Found data directory: '/data/data/com.example.native_plasma'
Found first launchable activity: android.app.NativeActivity
Launching activity: com.example.native_plasma/android.app.NativeActivity
## COMMAND: /opt/android-sdk-linux/platform-tools/adb shell am start -n com.example.native_plasma/android.app.NativeActivity
Starting: Intent { cmp=com.example.native_plasma/android.app.NativeActivity }
## COMMAND: /opt/android-sdk-linux/platform-tools/adb shell sleep 2
Found running PID: 0
ERROR: Could not extract PID of application on device/emulator.
Weird, this probably means one of these:
- The installed package does not match your current manifest.
- The application process was terminated.
Try using the --verbose option and look at its output for details.
This indicates that the application segfaulted more less, but I don't know how to set a breakpoint here since gdb never actually gives a prompt.
I also tried this command:
$ ../../toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-addr2line -f -e libs/armeabi/libnative-plasma.so
bedb2330
??
??:0
I have debug symbols I believe.
ndk-build -B V=1 APP_OPTIM=debug
Android.mk in jni/ has LOCAL_CFLAGS := -g
ant debug
I've also ndk-build NDK_DEBUG=1 but I still get where it looks like I don't have debug symbols.
Here's an image of the stack trace. It doesn't get any more informative:
Well NDK_DEBUG=1 and debuggable flag in manifest set to true are required. When you build the app,in your project/libs/armeabi, there should be a gdb.setup file. There is symbol search path there, check whether it is valid. And did you try this:
ndk-gdb --start --verbose --force
And looks like you are getting a null pointer exception.
In latest versions of NDK and Eclipse plug-in you can right click on package and choose Debug as -> Android Native Application
Make sure that you load your native library in either a launchable activity or in your Application class. Otherwise it wouldn't work and you'll get the following error No symbol table is loaded. Use the "file" command..
For example in Application class:
import android.app.Application;
public class MyApp extends Application {
static {
System.loadLibrary("Name");
}
public static native int doSomething();
}
Name is the name of your library (.so file) without the lib part.
I resolved putting --nowait option to the shell command:
ndk-gdb --start --verbose --nowait

Categories

Resources