I am developing an Android application using Kotlin programming language. I am writing instrumented tests for my application. I am also using the test orchestrator to run my instrumented tests. But after the installation of the test orchestrator modifying the Grandle file, I cannot run the test in the Android Studio.
I added the following configuration to the app.grandle file
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.example.memento"
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"
// testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunner "com.example.memento.MockTestRunner"
// Cleared between tests.
testInstrumentationRunnerArguments clearPackageData: 'true'
testOptions {
execution 'ANDROID_TEST_ORCHESTRATOR'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
With this
androidTestImplementation 'com.android.support.test:runner:1.1.1'
androidTestUtil 'com.android.support.test:orchestrator:1.1.1'
This is the MockTestRunner class
import android.app.Application
import android.content.Context
import androidx.test.runner.AndroidJUnitRunner
import com.example.utils.MockApplicationController
class MockTestRunner: AndroidJUnitRunner()
{
override fun newApplication(
cl: ClassLoader?,
className: String?,
context: Context?
): Application {
return super.newApplication(cl, MockApplicationController::class.java!!.getName(), context)
}
}
Then, in the Android Studio, I tried to run a test by right-clicking on the code as follows.
This is what I got when I run the test.
$ adb shell CLASSPATH=$(pm path android.support.test.services) app_process / android.support.test.services.shellexecutor.ShellMain am instrument -r -w -e targetInstrumentation com.example.memento.test/com.example.memento.MockTestRunner -e debug false -e class 'com.example.memento.EventListTest#eventListIndexZeroTabRendersCurrentEvents' -e clearPackageData true android.support.test.orchestrator/android.support.test.orchestrator.AndroidTestOrchestrator
Waiting for process to come online...
Started running tests
Test running failed: No test results
Literally, not tests were run. What is wrong with my configuration and how can I fix it. If I remove the test orchestrator installation, I can run the tests and it is working as expected.
Related
I have defined these into my build.gradle, to enable Orchestrator in my Android Instrumented tests:
defaultConfig {
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: 'true'
}
testOptions {
animationsDisabled = true
execution 'ANDROIDX_TEST_ORCHESTRATOR'
}
dependencies {
androidTestImplementation 'androidx.test:runner:1.5.1'
androidTestUtil 'androidx.test:orchestrator:1.4.2'
}
Sadly, when I start tests, data is not cleared and it persists between test runs.
I tried both, start test from Android Studio and by gradle cli ./gradlew connectedStageDebugAndroidTest
Any idea what I am doing wrong?
I'm using the AndroidJUnitRunner in my project, but the unit tests are painfully slow to execute on a device and emulator both in Android Studio and from the command-line via gradlew.
I'm using the master branch of this open-source project, OneBusAway (as of this commit):
https://github.com/OneBusAway/onebusaway-android
I'm seeing execution time of all 142 tests that is upwards of 3 minutes in real elapsed time, but Android only registers a smaller portion of this in the execution time it shows under "Test Results". Before switching to the AndroidJUnitRunner all of these unit tests executed under 20 seconds consistently.
Here's what an example test looks like:
/**
* Tests to evaluate utility methods related to math conversions
*/
#RunWith(AndroidJUnit4.class)
public class MathUtilTest {
#Test
public void testOrientationToDirection() {
// East
double direction = MathUtils.toDirection(0);
assertEquals(90.0, direction);
}
}
Here's the build.gradle config:
android {
dexOptions {
preDexLibraries true
}
compileSdkVersion this.ext.compileSdkVersion
buildToolsVersion "27.0.3"
defaultConfig {
minSdkVersion 14
targetSdkVersion 21
versionCode 93
versionName "2.3.8"
multiDexEnabled true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
// The following argument makes the Android Test Orchestrator run its
// "pm clear" command after each test invocation. This command ensures
// that the app's state is completely cleared between tests.
testInstrumentationRunnerArguments clearPackageData: 'true'
}
...
testOptions {
execution 'ANDROID_TEST_ORCHESTRATOR'
unitTests.includeAndroidResources true
}
...
}
dependencies {
...
// Unit tests
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestUtil 'com.android.support.test:orchestrator:1.0.2'
...
}
Why is this running unit tests so slow?
Apparently the slowdown is related to including a dependency on Android Test Orchestrator, which I don't need (even if I'm running tests on a device that require an Android context). It wasn't clear to me from the existing documentation that Orchestrator wasn't required for these tests.
I removed the following lines from build.gradle, and my total execution time via Android Studio dropped back down into the ~15 second range:
// The following argument makes the Android Test Orchestrator run its
// "pm clear" command after each test invocation. This command ensures
// that the app's state is completely cleared between tests.
testInstrumentationRunnerArguments clearPackageData: 'true'
...
execution 'ANDROID_TEST_ORCHESTRATOR'
...
androidTestUtil 'com.android.support.test:orchestrator:1.0.2'
So here's the new build.gradle that executes tests in ~15 seconds:
android {
dexOptions {
preDexLibraries true
}
compileSdkVersion this.ext.compileSdkVersion
buildToolsVersion "27.0.3"
defaultConfig {
minSdkVersion 14
targetSdkVersion 21
versionCode 93
versionName "2.3.8"
multiDexEnabled true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
...
testOptions {
unitTests.includeAndroidResources true
}
...
}
...
dependencies {
...
// Unit tests
androidTestImplementation 'com.android.support.test:runner:1.0.2'
}
I thought that maybe the testInstrumentationRunnerArguments clearPackageData: 'true' was the primary culprit causing increased execution time to clear the package data, but removing that line alone didn't change the total execution time of tests - I had to completely remove the Orchestrator dependency.
Here's the commit on Github that removed Orchestrator:
https://github.com/OneBusAway/onebusaway-android/commit/a1657c443258ac49b1be83a75399cf2ced71080e
I am trying to get code coverage for my Android project using Espresso tests. However, Jacoco is giving me back a report saying that I don't cover anything. I made a demo app to highlight my problem and that is here.
If you don't want to go to Github to look at the project, here is the build.gradle file:
apply plugin: 'com.android.application'
apply plugin: 'jacoco'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "ninja.bryansills.jacocotest"
minSdkVersion 16
targetSdkVersion 22
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
packagingOptions {
exclude 'LICENSE.txt'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
testCoverageEnabled true
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.1.1'
androidTestCompile 'com.android.support.test:runner:0.2'
androidTestCompile 'com.android.support.test:rules:0.2'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.1'
}
Based on the issue pointed out by Ligol, here is what worked for me.
Added custom test runner in androidTest
package com.example;
import android.os.Bundle;
import android.support.test.runner.AndroidJUnitRunner;
import android.util.Log;
import java.lang.reflect.Method;
public class AndroidJacocoTestRunner extends AndroidJUnitRunner {
static {
System.setProperty("jacoco-agent.destfile", "/data/data/"+BuildConfig.APPLICATION_ID+"/coverage.ec");
}
#Override
public void finish(int resultCode, Bundle results) {
try {
Class rt = Class.forName("org.jacoco.agent.rt.RT");
Method getAgent = rt.getMethod("getAgent");
Method dump = getAgent.getReturnType().getMethod("dump", boolean.class);
Object agent = getAgent.invoke(null);
dump.invoke(agent, false);
} catch (Throwable e) {
Log.d("JACOCO", e.getMessage());
}
super.finish(resultCode, results);
}
}
Used this test runner in app/build.gradle
android{
...
defaultConfig {
....
testInstrumentationRunner "com.example.AndroidJacocoTestRunner"
}
}
Your problem might be related to this issue.
https://code.google.com/p/android/issues/detail?id=170607
I had the same problem on Samsung device, I did not change anything but changed to HTC device I started getting the coverage.ec Something seems to be fishy with JaCoCo Samsung device.
I advise everyone not to use a Samsung device while generating coverage reports. I tried everything to fix the 0 coverage issue and luckily changed my device to Redmi Note 5 Pro and voila the coverage starts showing.
On doing some research and reading some articles I found Samsung give less freedom to its user to use their products for testing. Though you can do the testing on Samsung devices after rooting them.
I am trying to add some unit tests to my app. I am developing my app in Android Studio
This is what I did.
Added a new package
Created a class in new package which extends TestCase
Added following method to created class
#SmallTest
public void basicTest() {
assertEquals("abc", "abc");
}
Added following to defaultConfig section in build.gradle
testApplicationId "newly.added.package.name"
testInstrumentationRunner "android.test.InstrumentationTestRunner"
Executed following command in Android Studio Terminal
gradlew.bat connectedAndroidTest
But, when I checked the generated html report, it shows that 0 tests were run.
I tried following, but none of them made a difference to the output of gradlew.bat connectedAndroidTest command.
Added an incorrect package name to testApplicationId in build.gradle.
Disconnected device
Why doesn't my test case get executed? What have I missed?
Following is my build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 20
buildToolsVersion "21.1.1"
defaultConfig {
applicationId "my.package.name"
minSdkVersion 12
targetSdkVersion 18
testApplicationId "my.package.name.tests"
testInstrumentationRunner "android.test.InstrumentationTestRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
lintOptions {
abortOnError false
}
}
dependencies {
compile project(':my_sub_module1')
compile project(':my_sub_module2')
compile 'com.android.support:support-v4:21.0.2'
compile files('libs/my_dependent_lib-1-7-4.jar')
compile 'com.google.code.gson:gson:2.3'
}
repositories {
mavenCentral()
}
You should use the following testInstrumentationRunner:
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
Also, click Build Variants on the left side of Android Studio, and select
Android Instrumentation Tests
in the dropdown.
So I've set up a gradle project with android and tried to get some tests to run. Unfortunately they don't seem to. It's possible that I'm missing something obvious but here goes...
I am running gradle 1.11 and as I understand the documentation that's the new folder (since 0.9 I believe?) that should be used for tests.
So I have my testclass ::
package se.coinhunter.multigradle.test;
import org.junit.Test;
import static org.junit.Assert.*;
public class HelloAndroidTests {
#Test
public void testHelper() {
assertEquals(1,1);
}
}
}
That lives in src/androidTest and here is my build.gradle:
apply plugin: 'android'
android {
compileSdkVersion 19
buildToolsVersion "19.0.3"
defaultConfig {
minSdkVersion 11
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile 'com.android.support:appcompat-v7:+'
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':MultiGradleSubmodule')
}
This is a multi-project build and the submodule mentioned in the dependencies block is a plain java project that has its' own scource and unit tests running quite smoothly. I was able to specify that it should tell me when it runs its' tests and give me some feedback and that works fine. That was achieved for that project using
test {
testLogging {
events 'started', 'passed'
}
}
in its' build.gradle. I havn't come across anything like this for android projects. The whole project builds and runs, but I either can't get the tests to run, or they're running but I'm not getting any output.
You're using jUnit 4 (package name "org.junit" with #Test annotation). Android gradle only works with jUnit 3 (package name "junit.framework" with no annotations).
Android tests run in the Dalvik virtual machine on a device or emulator so your test class should also extend "AndroidTestCase" (or one of the other junit subclasses in Android - depending on what you're testing).
UPDATED: also add the following to default config:
testInstrumentationRunner "android.test.InstrumentationTestRunner"
testFunctionalTest true
Run the test using
gradle connectedCheck