Run robolectric and android unit test from Android studio - android

I currently have various AndroidTestCases which use Mockito and the module dexmaker-mockito. I am now trying to add Robolectric test cases using the robolectric plugin.
I have everything running fine except that when I try to mock methods with no arguements I get an IllegalArgumentException from Dexmaker. Removing the dexmaker-mockito dependency and using mockito version 1.9.0 instead of 1.9.5 causes the error to go away but causes all of my AndroidTestCases to fail. Is there anyway in gradle to have dexmaker-mockito exclude from my robolectric test cases? Or does anyone know of any other way to run both android unit test and robolectric unit test from android studio?
Error:
java.lang.IllegalArgumentException at com.google.dexmaker.mockito.InvocationHandlerAdapter.invoke
Update
I tried gradle-android-test-plugin and robolectric-gradle-plugin but was unable to to get rid of the IllegalArguementException without changing the version of mockitio to 1.9.0 and removing dexmaker, dexmaker-mockito from my dependencies.
I tried the guide but was unable to get Android Studio to recognize my source directories without adding them to main or test source sets which break my build because robolectric is not compiled for those gradle tasks and I do not want it to be.
I ended up following the guide here this time the error disappeared when I ran the tests from command line but persisted when running from android studio which I found odd. Again changing the version of mockitio to 1.9.0 and removing dexmaker, dexmaker-mockito from my dependencies in my Android App removed the error. For now I will settle for not being able to run the unit tests from android studio until I find a better answer.

If I understand correctly what dexmaker-mockito is supposed to do, it's meant to be used with Android Unit Tests that run on device, so it's good for your Android Test Cases.
Robolectric tests run on the JVM and should be run as JUnit test, not Android tests. They should not be using dexmaker-mockito as they never get deployed to device, they can just use the normal Mockito libraries, with scope set to test.
I think you may not be able to mix the two, you may have two keep your robo tests separate from your Android unit tests.

Related

Does Kotest (previously KotlinTest) still work in Android Studio?

As far as I can tell, Kotest requires JUnit 5:
https://github.com/kotest/kotest/issues/1104
It also requires Gradle 6:
https://github.com/kotest/kotest/issues/1301
I presume it's possible to get this all set up and working, but isn't it true that JUnit 5 and Gradle 6 are not really supported for Android development? I'm concerned that, even I get this all working now, I may have problems down the line.
Kotest does work on Android Studio.
JVM tests
To setup the JUnit 5 runner for your unit tests (plain JVM) you can follow the instructions at https://kotest.io/quick_start/.
Of course If you have an already started project with JVM JUnit4 tests you will have to make additional steps to configure both the runners for the JUnit4 and for the new JUnit5/Kotest tests, but it is outside of the scope of this answer.
Android Robolectric tests
You can find the instructions on how to set it up here. Given Robolectric ones are plain JVM tests and not instrumented ones, you can use the JUnit5 runner and they will run just fine.
Android instrumented tests
Apparently Kotest has a JUnit4 runner project too, but no instructions yet on how to set it up with Android.

How to connect android studio testing GUI to gradle task?

There are some tests in my android project and configured CI
Before deploying tests are launched using gradle wrapper(4.10.3)
95% of tests are robolectric tests
And there are cases when these tests are not passing because of different reasons, but the problem is that when i run them from android studio GUI tests are working fine(passing).
For example i use mockito for mocking and mock-maker-inline, i have this MockMaker in core module that is used in all other modules, if i launch tests from android studio - they are passing, if i launch using gradle wrapper - they are all failing. It can be solved by adding MockMaker in module, where i have tests, but still why it is working from android studio, but not working from console?
My test running options:
Case when i remove mock maker from locations module(dependent on core module with enabled mock-maker)
All tests are filing with this error
But when i run with android studio tests are passing and everything is fine.
What is the difference between these two launches?(default launch type from android studio and gradlew testDebug).
And is there a way to connect my custom gradle test task with android studio tests gui?
The biggest difference between the GUI and running from terminal is that the Gradle wrapper will execute the tests of different modules concurrently if you have it enabled in gradle.properties:
org.gradle.parallel=true
If you have tests in different modules acting upon the same singleton, or the same mocks, then you can run into any number of conflicts.

How to run unit tests with IDEA+Gradle+Android

I've written some unit tests in my Android projects with Robolectric, and some of them even don't use Android.
I've tried first this: robolectric-gradle-plugin, following this template.
The result is that I've faced this bug in IDEA, that I reported myself.
Then I've tried another possibility: the gradle-android-test-plugin, which separates tests in another submodule, that is a regular Java project. I've tried to follow this other template. I've open this bug report.
Then I've faced again with other bug.
What recommendations can you provide me, that does work?
Finally I've had to upgrade IDEA to 14 EAP, and know it works ok.
gradle-android-test-plugin seems to work better than robolectric plugin, as I can run JUnit and ScalaTest tests easily. I've had to install with a script, the non-published com.novoda:gradle-android-test-plugin:0.9.9-SNAPSHOT.
It's a hell the combination of versions of:
Android Build Tools
Gradle
com.android.tools.build:gradle
IDEA
robolectric
robolectric plugin
....
Any change in one of them, can make your project fail.
Luckily, by using Gradle you can fix the versions of every component, and do Continous integration.

Best way to run fast JUnit tests in Android project in Android Studio

I have some plain old Java classes and simple JUnit tests in my Android Studio project. They currently live inside my Android Module. If I run them as Android tests they pass fine, but they're really slow as it requires launching or connecting to the emulator.
If I try to run one as a JUnit test, I hit the !!! JUnit version 3.8 or later expected JUnit version problem. This answer explains how to workaround that issue. Unfortunately, I then hit the java.lang.NoClassDefFoundError: junit/textui/ResultPrinter, which I can't figure out how to fix.
I then tried to move my JUnit tests into a separate Java module that depends on the Android Module. Everything compiles fine. I added a new configuration to launch the JUnit tests (:MyJUnitTests:test), but the tests fail with package com.myproject.util does not exist. It looks like maybe the classpath isn't including the classes from the dependent Android Module.
Does anybody know how to fix this classpath issue? I've looked at lots of related answers and none of them seem to work for me. Or is it a just a bad idea to try and keep my JUnit tests in their own Module?
I can get the JUnit tests to run fast and pass if I move my plain Java classes and their JUnit tests into a completely separate Module (e.g. here), and reverse the dependency so the Android Module depends on the Java Module. Is that the preferred solution?
The basic problem is that Android Framework classes don't work well outside the context of Android OS, so any code that has dependencies on Framework classes doesn't run in a regular JUnit environment, as you've found.
Your solution of trying to move the JUnit tests into a separate module won't work because you can't have a plain Java module depend on an Android module. Android Gradle modules don't act like Java modules, because Android builds are much more complex, and because the end result of an Android module build will be an APK or an AAR, which other module types won't understand.
If you can move your plain Java classes and unit tests into a plain Java module and have the Android modules depend on that, it will be the best approach that will get the most support from official features in the IDE. It will also have an architectural benefit in that it will keep those classes free from Android abstractions, making it more portable, and enforcing a separation of business logic from UI or storage or other things more device-specific.
If that's difficult for you to do, then a lot of developers in your shoes go with Robolectric, which is a test harness allowing code depending on many parts of the Android Framework to run in a JUnit environment without an emulator or device. It's not officially supported by Google, but Google is aware that it's widely used and tries hard to not wantonly break it.

Unit tests in Android Studio 0.8

BREAKING NEWS: Android Studio 1.1.0 now has built-in support for unit testing. See more here: https://sites.google.com/a/android.com/tools/tech-docs/unit-testing-support
At first I know that there are very, very, very much similar questions (even here on SO). Most of them are terribly outdated so I'm asking a fresh new question which should be up to date for Android Studio 0.8.x.
I know there are some libraries which work somehow, but in almost each case I had no evidence that the information were up to date. I know there is e.g. roboelectric, there are also some deprecated Jake Wharton like gradle-android-test-plugin or double-espresso, I also found the library RoboSpock and Deckard. But none of them seems to have any Android Studio integration.
After long reseach I found this two bugs in all implementations:
The classpath is broken and needs to been hacked to get junit running
The junit tests cannot been debugged
What I'm looking for:
I want to automatically test an algorithm (which is plain java)
I want to check the integration in my Android app works
I want an integration in Android Studio so that I can jump into the code out of a stacktrace
I want to step thrue the test code
I found also somewhere a nice hack which run the tests in gradle as an external task and pushed the results into AS so that the results could been displayed, but unfortunately I cannot find that link again (and if I remember correctly it did also not work for me).
Do you guys have some fresh references? Does it work for you?
You have to edit the .iml file that Android Studio generates to point to your test-classes directory and also to fix the Stub error from Junit. There is currently no work around for this.
Gradlectric is a sample that uses the Robolectric Gradle Plugin to run unit tests in Android Studio.
Here you miss one example project setup https://github.com/nenick/android-gradle-template
But none of them seems to have any Android Studio integration.
This project is maintained for android studio
The classpath is broken and needs to been hacked to get junit running
gradle scripts will fix the classpath
The junit tests cannot been debugged
tests a running inside AS so they are easy to debug
This project of mine does not cover all your requests, but a fair lot of them.
It covers a default Java test case, and some tests interacting with Views.
The root project uses Travis CI, which uses gradle connectedCheck to run the tests. To be able to debug the tests, you can just create a test run configuration in AS and run it in debugging mode.
Note that this does not use any special Android testing frameworks like robolectric.
You can find a fork of Jake Wharton's gradle-android-test-plugin here. This is compatible with AS 0.6 and is regularly maintained by Robolectric. You can look at this project to set up Robolectric in Android Studio with help of this plugin. You can achieve fair bit of functionality you mentioned with the help of robolectric-gradle-plugin. You can also successfully debug your test code using AS.

Categories

Resources