Android Instrumentation test does not find classes from library project - android

So I'm getting a NoSuchMethodError when running my Activity/instrumentation tests from Android Studio, on the code line which tries to call a method in a library module from the unit test.
So this is my test:
public class MainActivityTest extends ActivityInstrumentationTestCase2 {
public void testMainActivity() {
final MainActivity target = (MainActivity) getActivity();
MyLibarary.someStaticMethod(); // yields java.lang.NoSuchMethodError
}
What's the deal here? I've defined my library as a "compile"-dependency in build.gradle, and it's compiling just fine. The library is also invoked from the main app classes without problems. It's only when I call it from the tests it fails. My app and my tests are in the same module.
I've tried running the clean task, the assembleDebug and assembleDebugTest tasks manually. No avail.
Project structure:
Root
|---MyApp
| |---src/main/...
| |---src/androidTest/...
|----MyLibrary
Running Android Studio v1.0.2
Gradle build tools v1.0.0
Running as an "Android Test" on module "MyApp" from the Run/Debug configurations of AS with default Instrumentation test runner.

Ok this one was a bit tricky. Keyword: proguard minify. Since the newly implemented method so far only was used by the instrumentation test, proguard didn't pick up on its usage and therefore removed it from the DEX in the proguardDebugTest build step.
Solution: Either disable minification in the debug build (In gradle: android.buildTypes.debug.minifyEnabled false), or use the method in the main app.

Not really up-to-date with Gradle. But i think we are supposed to specify the testCompile or the androidTestCompile dependency as well in the build.gradle if trying to write instrumentation tests.
Helpful Links:
http://gradle.org/docs/current/userguide/java_plugin.html
Specifying test dependencies with the Gradle Android build system
Hope this helps

Related

java.lang.NoClassDefFoundError: Test Module could not resolve classes of other Feature Module, Unit Testing - Kotlin - Android

I have the following Project Structure:
Main App
--app
--featureModule1
--featureModule2
--TestKit(Library module)
where Testkit has all dependencies including app and featureModules. The Testkit included all the unit tests related to the features in app and featuremodules.
When i run unit tests from Android studio(Right click-> Run Test in Testkit), they run fine. However whenever i try running it from gradle command: ./gradlew TestKit:testInternalDebugUnitTest, it throws NoClassDefFoundError for all the dependencies of other modules(for both app and feature modules).
Also i have already added implementation and testImplementation dependencies of all the modules in test module.
Please suggest:
Do i need to add path of classes generated in other modules, if yes pls guide where.
Also running Test with Coverage fails with
java.lang.VerifyError: Bad return type
Please suggest what am i doing wrong here.
Note:
I have created a Testkit because of the multiple open issues of Roboelectric in feature modules for ex: https://github.com/robolectric/robolectric/issues/5428
Versions
AS: 4.0.1
gradle: 4.0.1
gradle-wrapper: 6.5
Robolectric: 4.3.1
I was able to solve the problem using the following runtime test dependencies:
testRuntimeOnly(files("${projectDir}/../app/build/intermediates/app_classes/internalDebug/classes.jar"))
testRuntimeOnly(files("${projectDir}/../featureModule1/build/intermediates/app_classes/internalDebug/classes.jar"))
testRuntimeOnly(files("${projectDir}/../featureModule2/build/intermediates/app_classes/internalDebug/classes.jar"))
inside build.gradle of Testkit.
Can refer to the following link for more details:https://github.com/android/app-bundle-samples/issues/11#issuecomment-675725610

Exclude Gradle #LargeTest

I am trying to run unit test on a separate task from the UI tests that I have within the integration tests in Android Studio, unfortunately I have to use
apply plugin: 'com.android.application'
in the build.gradle file so I cannot add the custom test tasks as far as I can tell. Since the UI tests are tagged as "#Test" and extend InstrumentationTestCase they get run whenever
gradle connectedCheck
is called which is not needed, instead I want one gradle command to run UI tests and one to run unit tests. I figured that I would be able to leverage tagging the UI tests as LargeTests but have not been able to complete a gradle task that can do this. I am not able to use the "test" task in the build.gradle since we are using the com.android.application plugin, and advice?
Thanks
You can do this from command-line without modifying the build.gradle file:
./gradlew cAT -Pandroid.testInstrumentationRunnerArguments.notAnnotation=android.test.suitebuilder.annotation.LargeTest
What ended up working for me is adding the
#LargeTest
using
import android.support.test.filters.LargeTest;
annotation to the tests I needed and then adding the following lines to the build.gradle
if(!project.hasProperty('android.testInstrumentationRunnerArguments.annotation')) {
testInstrumentationRunnerArgument 'notAnnotation', 'android.support.test.filters.LargeTest'
}
this way unless I specify in the command line to run the large tests they will,be ignored. To run the large tests use:
gradle cAT -Pandroid.testInstrumentationRunnerArguments.annotation=android.support.test.filters.LargeTest

Android unit test support does not work in android library modules

I am writing junit tests on android project using the new unit test support http://tools.android.com/tech-docs/unit-testing-support.
While the unit tests run on the 'com.android.application' module perfectly but they always fail on the 'com.android.library' modules. This has not been documented in http://tools.android.com/tech-docs/unit-testing-support . So I wonder whether I am the culprit.
When I write those tests on library modules, the tests can not find the classes on the module and always gives following errors:
package does not exist
error: cannot find symbol
The android unit test support is in experimental phase right now, but is there a solution to it.
UPDATE
I have added this issue to android issue tracker https://code.google.com/p/android/issues/detail?id=161038
It looks like the task to compile the unit tests doesn't depend on the task to compile the library code.
The following fixed it for me:
afterEvaluate {
tasks['assembleDebugUnitTest'].dependsOn(tasks['assembleDebug'])
}
I run the tests using
./gradlew testDebug
If you don't want to modify your build.gradle, manually specify the assembleDebug task on the command line should also do the trick:
./gradlew assembleDebug testDebug
In my android library project I also failed to get the tests running. What I did was create a test application that uses the library and wrote tests in the application that call the library methods.
This might not be the ideal solution, but was the way we got this to work.
Have a look over here https://github.com/nenick/AndroidStudioAndRobolectric
There you can run unit tests on libraries and flavors. And no you don't need to use Robolectric as Gaurav Vashisth stated. You can if you want to.
Here is an example of JUnit test in a library module

No Dagger2 generated files for JUnit tests

A new AndroidStudio 1.1 version introduced the unit testing support. This URL http://tools.android.com/tech-docs/unit-testing-support provides step-by-step instruction how to setup IDE to run JUnit tests for Android sources.
This plugin https://bitbucket.org/hvisser/android-apt used to provide Dagger2 generated files to AS and it works OK for usual Android code but unfortunately there is no generated Dagger2 files for any JUnit test class. I tried to configure dependency like
androidTestApt 'com.google.dagger:dagger-compiler:2.0-SNAPSHOT'
according to android-apt plugin documentation but without success.
I think the problem is in different sources directory for Unit tests - it's src/test/java instead of src/androidTest/java that used by android instrumentation tests.
Can you please provide any help or info how to resolve this trouble?
Having
// You version may vary
androidTestApt 'com.google.dagger:dagger-compiler:2.0-SNAPSHOT'
in your dependencies, open a terminal in your project, run
./gradlew assembleTest
This will generate the Dagger component classes living under your androidTest source set.
Go back to Android Studio, the class now exists and can be used.

Android Studio 1.1, simple junit test setup

I have read around, there are a number of extensive answers (like this one) but the Android world evolves so fast that they seem to be a bit outdated and the official documentation still refers to Eclipse with ADT.
I am running AS 1.1 and I am trying to setup simple junit tests to run on the emulator, without Robolectric. If I don't include junit in my build.gradle, it can't find #After, #Before and #Test and I get package org.junit does not exist. Upon adding
// unit tests
androidTestCompile 'junit:junit:4.11'
the error becomes
Error:duplicate files during packaging of APK
[...]/app/build/outputs/apk/app-debug-test-unaligned.apk
Path in archive: LICENSE.txt
Origin 1: [...]/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/42a25dc3219429f0e5d060061f71acb49bf010a0/hamcrest-core-1.3.jar
Origin 2: [...]/.gradle/caches/modules-2/files-2.1/junit/junit/4.11/4e031bb61df09069aeb2bffb4019e7a5034a4ee0/junit-4.11.jar
You can ignore those files in your build.gradle:
android {
packagingOptions {
exclude 'LICENSE.txt'
}
}
Following the console suggestion of excluding LICENSE.txt, it then works but it feels like a hack. So I'm wondering, am I maybe missing something? Thanks.
Android Studio unit testing support comes in 1.1 Beta 4 (release announcement) with Gradle plugin version 1.1.0-rc1.
More info in official document.
However it is experimental feature for now. E.g. it breaks installDebug gradle task.
For using JUnit in instrumentation tests there is good guide for Espresso library and another covering new AndroidJUnitRunner.
If it's any use I set up a boiler plate project allowing the use of Unit tests and Espresso tests by the use of switching build variants. You won't need the use of any third party plugins with this.
https://github.com/hitherejoe/Android-Boilerplate

Categories

Resources