Julius
Julius

Reputation: 509

Running Espresso tests on Android 4.4?

I'm trying to migrate our app to using Espresso for UI testing, but I'm unable to make Gradle find my tests with a device running Android 4.4 (API 19, our minimum deployment target). Tests on Android 6.0 (API 23) run fine. I added the JUnit runner and the dependencies to app/build.gradle according to this and this (I excluded annotations because of version conflicts between the modules):

android {
...
    defaultConfig {
...
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
}

dependencies {
...
    androidTestCompile("com.android.support.test.espresso:espresso-core:2.2.2") {
        exclude module: 'support-annotations'
    }
    androidTestCompile("com.android.support.test:runner:0.5") {
        exclude module: 'support-annotations'
    }
    androidTestCompile("com.android.support.test:rules:0.5") {
        exclude module: 'support-annotations'
    }
}

Then I created the required directory structure app/src/androidTest/java/ and a package com.companyname.appname and a java class EspressoTest.java with some mock test code:

@RunWith(AndroidJUnit4.class)
public class EspressoTest {

    @Rule
    public ActivityTestRule<TermsOfUse> termsOfUseActivityTestRule = new ActivityTestRule<>(TermsOfUse.class);

    @Test
    public void iAmAtTouView() {
        onView(withId(R.id.terms_of_use_content)).check(matches(isDisplayed()));
    }
}

If I right-click on the test class EspressoTest and choose "Run 'EspressoTest'" I get an error:

$ adb shell am instrument -w -r   -e package com.companyname.appname -e debug false com.companyname.appname.qa.test/android.support.test.runner.AndroidJUnitRunner
Client not ready yet..
Started running tests
Test running failed: Instrumentation run failed due to 'Process crashed.'
Empty test suite.

Also if I enter ./gradlew connectedAndroidTest in the command line I get:

Starting 0 tests on GT-I9305 - 4.4.4
Tests on GT-I9305 - 4.4.4 failed: Instrumentation run failed due to 'Process crashed.'

com.android.builder.testing.ConnectedDevice > No tests found.[GT-I9305 - 4.4.4] 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).
:app:connectedAuditDebugAndroidTest FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:connectedAuditDebugAndroidTest'.
> There were failing tests. See the report at: 
...

So to me it seems like Gradle doesn't recognize my test class when trying to execute test tasks with an Android device. How can I fix this?

Upvotes: 1

Views: 1172

Answers (3)

Thomas Keller
Thomas Keller

Reputation: 6060

Any chance you had to enable multidex, because your *-androidTest.apk contained more than 64k methods?

If so, you need to make sure that the first dex file (classes.dex) contains all the *Test classes that you want to run. You can configure this like this:

android {
    defaultConfig {
        multiDexEnabled true
        multiDexKeepProguard file('multidex-config.pro')
    }
}

and in your multidex-config.pro you add regular -keep rules for your test classes, e.g.

-keep class path.to.my.package.**.*Test { *; }

If your test classes have dependencies outside of your own package path, be sure to include those as well with separate -keep statements. Look out for java.lang.ClassNotFoundException in adb logcat to identify missing classes.

Upvotes: 1

张小贤
张小贤

Reputation: 41

Added additional info for Thomas Keller's answer:

-keep path.to.my.package.**.*Test { *; }

has syntax error, it should be:

-keep class path.to.my.package.**.*Test { *; }

According to Android guide:

https://developer.android.com/studio/build/multidex?#multidexkeepproguard-property

It worked for me. I run instrument test on Android 4.4.

When I found the key message in logcat that the test runner only search classpath in the main DEX path, even though the secondary dex is already processed by androidx.multidex.

D/dalvikvm( 7758): DexOpt: --- END 'com.byted.bytexx.test-1.apk.classes2.zip' (success) ---
D/dalvikvm( 7758): DEX prep '/data/data/com.byted.bytexx.test/code_cache/secondary-dexes/com.byted.bytexx.test-1.apk.classes2.zip': unzip in 109ms, rewrite 1745ms
I/MultiDex( 7758): install done
I/MonitoringInstr( 7758): Instrumentation started!
I/MultiDex( 7758): Installing instrumentation
I/MultiDex( 7758): Installation done

...

I/TestRequestBuilder( 7758): Scanning classpath to find tests in paths [/data/app/com.byted.bytexx.test-1.apk]

...

D/TestExecutor( 7758): Adding listener androidx.test.internal.runner.listener.ActivityFinisherRunListener
I/TestRunner( 7758): run started: 1 tests
I/TestRunner( 7758): run finished: 0 tests, 0 failed, 0 ignored
I/MonitoringInstr( 7758): waitForActivitiesToComplete() took: 0ms
D/AndroidRuntime( 7741): Shutting down VM

And I found my test code is not in the main DEX.

Upvotes: 0

Testing Singh
Testing Singh

Reputation: 1353

First check what tasks are avaliable for gradle to run by:

gradle <app-module>:tasks

or

gradle --gui

See if the task you are running is in the list of tasks. Also which machine are you trying to run: MacOS or Windows? Always run gradle with 'sudo' if not at least sync your project from android studio always a good idea before running the tests

Upvotes: 0

Related Questions