Using android gradle + dagger to run instrumentTests - android

I have began using Android Studio and gradle recently for android development and find it much better overall than eclipse/ant or maven. However I've recently began trying to implement some kind of unit and or integration tests with my app. I was able to get basic tests working using the Espresso framework recently released by google. I had some tests though where I needed to mock and inject mocked versions of objects. I used dagger in the past for another project so I included dagger into my project. However now my tests won't run because of the following error:
gradle connectedCheck
...
4.1.2 failed: Instrumentation run failed due to 'java.lang.IllegalAccessError' :EspressoApp:connectedCheck
I created a simple demo of this here:
https://github.com/mwolfe38/android-espresso-dagger
Just clone and then from command line run: gradle connectedCheck
In the above I have tried the dependencies several different ways, originally like this:
dependencies {
compile 'com.android.support:appcompat-v7:+'
compile 'com.squareup.dagger:dagger-compiler:1.1.0'
compile 'com.squareup.dagger:dagger:1.1.0'
instrumentTestCompile files('libs/espresso-1.0-SNAPSHOT.jar',
'libs/testrunner-1.0-SNAPSHOT.jar',
'libs/testrunner-runtime-1.0-SNAPSHOT.jar')
instrumentTestCompile 'org.hamcrest:hamcrest-all:1.3'
instrumentTestCompile 'com.google.guava:guava:15.0'
}
but that gives me an error regarding static initialization. This appears to be caused by some static initialization code in the espresso framework regarding dagger. So After adding dagger dependencies to instrumentTestCompile I get the IllegalAccessError mentioned above.
Anyone have luck including dagger in your project and doing espresso tests?

Took quite awhile but I finally got it working. I had to do the following:
Declare my dependencies like so:
dependencies {
compile 'com.android.support:appcompat-v7:+'
compile 'com.squareup.dagger:dagger-compiler:1.1.0'
compile 'com.squareup.dagger:dagger:1.1.0'
instrumentTestCompile files('libs/espresso-1.0-SNAPSHOT.jar','libs/testrunner-1.0-SNAPSHOT.jar','libs/testrunner-runtime-1.0-SNAPSHOT.jar')
instrumentTestCompile files('libs/hamcrest-core-1.1.jar', 'libs/hamcrest-library-1.1.jar', 'libs/hamcrest-integration-1.1.jar')
instrumentTestCompile 'com.google.guava:guava:14.0.1'
}
Copy the hamcrest jars from here
Remove the license files from the jars like this (or else you'll get an error about duplicate LICENSE.txt files)
zip -d hamcrest-core-1.1.jar LICENSE.txt
zip -d hamcrest-library-1.1.jar LICENSE.txt
Run gradle connectedCheck
A few things to note:
- Hamcrest 1.3 didn't work for me, got an error about a matcher was missing
- Crazy how many hoops I had to jump through to get here.
- Good luck getting this to play well with android studio.

Ok, so I have been dealing with this problem for hours, and here is my fix:
Put this in the dependencies of your build.gradle
compile(project(':commons:statemachine')) {
exclude module: 'junit'
exclude module: 'json'
exclude module: 'guava'
}
compile 'com.google.guava:guava:15.0'
instrumentTestCompile files('libs/espresso-1.0-SNAPSHOT-bundled.jar')
instrumentTestCompile 'com.squareup:fest-android:1.0.+'
Add the espresso bundled jar in the libs folder of your test. Now comes the important part.
Open that espresso bundled jar with WinRar or equivalent and go to com/ folder, then select de android folder and Delete it. Now close WinRar and compile and run your test :-)

Related

dexmaker gradle sync fails, and symbol not resolved

gradle sync keeps failing with my android studio. need help
https://github.com/linkedin/dexmaker This is the open source i am trying to use called dexmaker.
I tried to download by using
androidTestCompile 'com.linkedin.dexmaker:dexmaker-mockito-inline:2.21.0'
but it gets errors like this
Failed to resolve: com.linkedin.dexmaker:dexmaker-mockito-inline:2.21.1
I finally tried
androidTestCompile 'com.linkedin.dexmaker:dexmaker-mockito-inline:2.19.1'
this works but in my java code
The problem is even though i succeeded on syncing gradle, i still can't use the opensource.
DexMaker dexMaker = new DexMaker();
DexMaker gets red lines and if i click it it says
cannot resolve symbol 'DexMaker'
what's the problem?
I'm not sure, but as I understand your situation:
You add dependency using androidTestCompile directive. That means that this package will become available only inside android test classes. For more understanding each dependency could be added in three ways: compile, testCompile and androidTestCompile.
compile : Dependency is available everywhere in your application code.
testCompile : Dependency available only in regular tests.
androidTestCompile : Dependency available only in android tests.
So if you want that dependency to be available in your application - replace androidTestCompile with compile. But I not sure, that you SHOULD do that, cause that library is for tests.
P.S. Using compile directives is deprecated and you should use implementation, testImplementation and androidTestImplementation.

Cannot resolve symbol 'AndroidJUnit4' for Android instrumentation test

This error has been faced a lot before and asked here. According to the answers, i had to put my instrumentation tests under androidTest folder. So after that, in my case, am still unable to import the AndroidJunit4 class and the pop-up suggestion dialog has now a new option : Setup JDK wich i am surprised with. Anyway i have followed the option and chosen the proper JDK but the problem is still there and the dialog still suggests the same option.
Does anyone know what is the problem here ?
EDIT : My gradle dependencies:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:support-annotations:23.4.0'
compile 'com.android.support:design:23.4.0'
compile 'com.parse.bolts:bolts-tasks:1.3.0'
compile 'com.parse:parse-android:1.13.1'
androidTestCompile 'junit:junit:4.12'
androidTestCompile 'com.android.support:support-annotations:23.4.0'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
}
I was banging my head against the wall and/or any object i see in front of me in order to make my SQLite function unit tested. No matter what I do, how strictly follow the suggestions provided my many wise people all over the internet did not work.
I then had to go to preschool and start over to realize my stupid mistake. I learned that AndroidJUnit4 can only be used with Instrumentation Test and JUnit must be used for local tests. That being said, the folder must be src/androidTest/java. I had my test class directly under androidTest folder, hence I had to face that nasty error. However, the moment I moved it under src/androidTest/java everything went very clear like "I can see clearly now the rain is gone".
Take a look at this article which says...
Run Instrumented Unit Tests To run your instrumented tests, follow
these steps:
Be sure your project is synchronized with Gradle by clicking Sync
Project in the toolbar. Run your test in one of the following ways:
To run a single test, open the Project window, and then right-click a
test and click Run . To test all methods in a class, right-click a
class or method in the test file and click Run . To run all tests in a
directory, right-click on the directory and select Run tests . The
Android Plugin for Gradle compiles the instrumented test code located
in the default directory (src/androidTest/java/), builds a test APK
and production APK, installs both APKs on the connected device or
emulator, and runs the tests. Android Studio then displays the results
of the instrumented test execution in the Run window.
Therefore folks, for instrumentation test the folder must be (do not forget the case)
src/androidTest/java
and for local tests the folder must be
src/test/java
You can then have your package folder(s) to match your app package
Hope, this helps for the community!

Problems setting up junit & mockito in Android Studio

I want to setup my project for unit testing.
I tried to follow the instructions on Android's page:
// Unit testing dependencies
testCompile 'junit:junit:4.12'
// Set this dependency if you want to use Mockito
testCompile 'org.mockito:mockito-core:1.10.19'
// Set this dependency if you want to use Hamcrest matching
androidTestCompile 'org.hamcrest:hamcrest-library:1.1'
However, when doing that and creating a test, I get:
"Cannot resolve symbol 'junit'"
"Cannot resolve symbol 'mockito'"
In Vogel's tutorial, a lot more dependencies are required, and I want the bare minimum.
Also, using Vogel's tutorial, I get:
Warning:Conflict with dependency 'com.android.support:support-annotations'. Resolved versions for app (22.2.1) and test app (22.2.0) differ.
So my question is: How can I get the dependencies from Android's page to work?
The support-annotations issue is a known one. You can find the info in their issue tracker. To workaround it, in the main (app, not module) build.gradle file, section allprojects add
configurations.all {
resolutionStrategy.force 'com.android.support:support-annotations:22.2.0'
}
(see answer #11 in the same link).
About the extra dependencies, you are going to need dexmaker and dexmaker-mockito for using mockito for your tests in devices/emulator, as they run on a Dalvik VM that expects .dex files, while mockito generates .class files. Unit testing as in the newest unit testing added to Android Studio, runs in your local JVM so it should probably run without dexmaker, but I cannot confirm this as of yet.

How to run ProGuard on Android tests?

We have a project with some library (and native) dependencies, like this:
Native SDK ← Library (Wrapper) ← Main Project
To start with, this structure cannot be changed, as we are reusing the parts. The problem I am facing is passing the 65k reference limit. This, of course, has a workaround - enable ProGuard. With it enabled, the project compiles.
Since we are transitioning to the Android's default testing framework, we need to add some more dependencies to the testing config, so in dependencies we now have:
compile 'com.google.android.gms:play-services-base:7.5.0'
compile 'com.google.android.gms:play-services-gcm:7.5.0'
compile 'com.google.android.gms:play-services-safetynet:7.5.0'
compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.android.support:recyclerview-v7:22.2.1'
compile files('libs/small-library1.jar')
compile files('libs/small-library2.jar')
compile files('libs/small-library3.jar')
compile files('libs/medium-library1.jar')
compile files('libs/medium-library2.jar')
compile files('libs/medium-library3.jar')
compile files('libs/huge-library1.jar')
compile files('libs/huge-library2.jar')
androidTestCompile 'com.android.support.test:runner:0.3'
androidTestCompile 'com.android.support.test:rules:0.3'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2'
We are using SDK (API) 22, so everything is pretty much at the latest version. The problem is, our native SDK has a bunch of code in the protobuf layer, and the library wrapper is big. With all other JARs, we are too high over the 65k limit (but as I said, ProGuard fixes this barely). Multi-dex is out of the question as it works well only on Android 5.0+.
We're trying to reduce the codebase, but even then, Android Tests are failing with method reference overflow issues (i.e. not compiling).
Is there any way to enable ProGuard for tests as well?
One option is to change your test build using testBuildType to the release build or another build variant that has ProGuard enabled. See Gradle User Guide. You can also try the solution here, but I have not tried that myself.

Android Studio Library module reference

I'm trying to setup my project so i can run unit tests and automation tests thru Android Studio. After many attempts i ended up with this structure on my project.
Project
-> Android Module (With the real app where i run the automation tests)
-> Java Library Module (With business logic classes and all things that i need to run unit tests)
I'm also referencing some Jar Lib on the Java Module in order to use some common code that i've wrote.
The Android Module references the Library Module as can be seen on the following sample gradle script:
dependencies {
compile project(':Core')
compile files(':Core/libs/fake_lib.jar')
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:19.+'
}
The second line on the dependencies section was need for the project can get assembled and run, but the problem is that on the first call to any class that have some reference to the library, the app crashes with a NoClassDefFoundError
Does anyone knows why and how to fix?
Since this JAR is a common library that i will use to many projects, i ended up placing it on my local maven repository and referenced it like other maven artifacts.
This way i don't have to reference it on both projects (Android and Java Library) just in the library, which i think is better approach.

Categories

Resources