Running simple JUnit tests on Android Studio (IntelliJ) using Gradle based configuration

I am using Android Studio/IntelliJ to create an existing Android project and would like to add some simple JUnit tags. What is the correct folder for adding such tests?

The android Gradle plugin defines the directory structure with src/main/java for the main source code and src/instrumentTest/java for Android .

Trying to add my JUnit tests to instrumentTest did not help me. I can run it as an Android test (which is what the directory is for), but this is not what I'm looking for - I just want to run a simple JUnit test. I tried to create a JUnit launch configuration for this class, but it also did not work - I suppose because I use the directory labeled Android Test instead of Source.

If I create a new source folder and mark it as such in the project structure, this will be cleared next time IntelliJ updates the project configuration from the gradle build files.

What is the most suitable way to configure JUnit tests in an Android project on gradle on IntelliJ ? What directory structure to use for this?

+76
android intellij-idea android-studio junit gradle
Jul 24 '13 at
source share
6 answers

Starting with Android Studio 1.1, the answer is simple: http://tools.android.com/tech-docs/unit-testing-support

+22
Feb 11 '15 at 20:53
source share

Usually you can’t. Welcome to the world of Android, where all tests must be performed on the device (except Robolectric).

The main reason is that you don’t actually have a framework source — even if you convince the IDE to run the test locally, you will immediately get a “Stub! Not Implement” exception. "What for?" can you ask a question? Since android.jar , which gives you the SDK, everything is actually crossed out - all classes and methods are there, but they all just throw an exception. It is there to provide an API, but not there to give you a real implementation.

There's a wonderful project called Robolectric that implements many of the frameworks so that you can run meaningful tests. Combined with a good mock frame structure (like Mockito), it makes your work manageable.

Gradle plugin: https://github.com/robolectric/robolectric-gradle-plugin

+36
Jul 24. '13 at 22:01
source share

Introduction

Please note that at the time of writing, robolectric 2.4 is the latest version and does not support the appcompat v7 library. Support will be added in the release of robolectric 3.0 (there is no ETA yet). Also, ActionBar Sherlock can cause problems with robolectric.

To use Robolectric in Android Studio, you have 2 options:

(Option 1) - Running JUnit tests using Android Studio using the Java module

This method uses a java module for all your tests with the dependency of your android module and a custom test runner with some magic:

Instructions can be found here: http://blog.blundellapps.com/how-to-run-robolectric-junit-tests-in-android-studio/

Also check the link at the end of this post to run tests from android studio.

(Option 2) - Running JUnit tests using Android Studio using robolectric-gradle -plugin

I'm having trouble setting up junit tests to run from gradle in Android Studio.

This is a very simple example project to run junit tests from the gradle project in Android Studio: https://github.com/hanscappelle/android-studio-junit-robolectric This has been tested with Android Studio 0.8.14, JUnit 4.10, robolectric gradle plugin 0.13 + and robolectric 2.3

Buildscript (project / build.gradle)

The script line is the build.gradle file in the root of your project. There I had to add the robolectric gradle plugin to the classpath

 buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:0.13.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files classpath 'org.robolectric:robolectric-gradle-plugin:0.13.+' } } allprojects { repositories { jcenter() } } 

Buildscript project (App / build.gradle)

In the build script of your application module, use the robolectric plugin, add the robolectric configuration and add the androidTestCompile dependencies.

 apply plugin: 'com.android.application' apply plugin: 'robolectric' android { // like any other project } robolectric { // configure the set of classes for JUnit tests include '**/*Test.class' exclude '**/espresso/**/*.class' // configure max heap size of the test JVM maxHeapSize = '2048m' // configure the test JVM arguments jvmArgs '-XX:MaxPermSize=512m', '-XX:-UseSplitVerifier' // configure whether failing tests should fail the build ignoreFailures true // use afterTest to listen to the test execution results afterTest { descriptor, result -> println "Executing test for {$descriptor.name} with result: ${result.resultType}" } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile 'org.robolectric:robolectric:2.3' androidTestCompile 'junit:junit:4.10' } 

Create JUnit Test Classes

Now put the test classes in the default folder (or update gradle config)

 app/src/androidTest/java 

And name your test classes ending with Test (or update config again) by extending junit.framework.TestCase and comment on test methods with @Test .

 package be.hcpl.android.mytestedapplication; import junit.framework.TestCase; import org.junit.Test; public class MainActivityTest extends TestCase { @Test public void testThatSucceeds(){ // all OK assert true; } @Test public void testThatFails(){ // all NOK assert false; } } 

Test execution

Then run the tests using gradlew from the command line (if necessary, run it with chmod +x )

 ./gradlew clean test 

Output Example:

 Executing test for {testThatSucceeds} with result: SUCCESS Executing test for {testThatFails} with result: FAILURE android.hcpl.be.mytestedapplication.MainActivityTest > testThatFails FAILED java.lang.AssertionError at MainActivityTest.java:21 2 tests completed, 1 failed There were failing tests. See the report at: file:///Users/hcpl/Development/git/MyTestedApplication/app/build/test-report/debug/index.html :app:test BUILD SUCCESSFUL 

Troubleshooting

alternative source directories

Just as you can have your java source files somewhere else, you can port your test source files. Just update gradle sourceSets configuration.

  sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } androidTest { setRoot('tests') } } 

org.junit package does not exist

You forgot to add a junit test dependency in your build script application

 dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile 'org.robolectric:robolectric:2.3' androidTestCompile 'junit:junit:4.10' } 

java.lang.RuntimeException: Stub!

You use this test with launch options from Android Studio instead of the command line (Terminal tab in Android Studio). In order to run it from Android Studio, you need to update the app.iml file to have the jdk entry below. See the deckard-gradle example for more details.

An example of a complete error:

 !!! JUnit version 3.8 or later expected: java.lang.RuntimeException: Stub! at junit.runner.BaseTestRunner.<init>(BaseTestRunner.java:5) at junit.textui.TestRunner.<init>(TestRunner.java:54) at junit.textui.TestRunner.<init>(TestRunner.java:48) at junit.textui.TestRunner.<init>(TestRunner.java:41) at com.intellij.rt.execution.junit.JUnitStarter.junitVersionChecks(JUnitStarter.java:190) at com.intellij.rt.execution.junit.JUnitStarter.canWorkWithJUnitVersion(JUnitStarter.java:173) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:56) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134) 

ERROR: JAVA_HOME is installed in an invalid directory

See this SO question for a solution. Add the bash profile below to you:

 export JAVA_HOME=`/usr/libexec/java_home -v 1.7` 

Full error log:

 ERROR: JAVA_HOME is set to an invalid directory: export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home Please set the JAVA_HOME variable in your environment to match the location of your Java installation. 

Test class not found

If you want to run tests from the Android Studio Junit Test runner, you will have to expand the build.gradle file a bit so that Android Studio can find your compiled test classes:

 sourceSets { testLocal { java.srcDir file('src/test/java') resources.srcDir file('src/test/resources') } } android { // tell Android studio that the instrumentTest source set is located in the unit test source set sourceSets { instrumentTest.setRoot('src/test') } } dependencies { // Dependencies for the `testLocal` task, make sure to list all your global dependencies here as well testLocalCompile 'junit:junit:4.11' testLocalCompile 'com.google.android:android:4.1.1.4' testLocalCompile 'org.robolectric:robolectric:2.3' // Android Studio doesn't recognize the `testLocal` task, so we define the same dependencies as above for instrumentTest // which is Android Studio test task androidTestCompile 'junit:junit:4.11' androidTestCompile 'com.google.android:android:4.1.1.4' androidTestCompile 'org.robolectric:robolectric:2.3' } task localTest(type: Test, dependsOn: assemble) { testClassesDir = sourceSets.testLocal.output.classesDir android.sourceSets.main.java.srcDirs.each { dir -> def buildDir = dir.getAbsolutePath().split('/') buildDir = (buildDir[0..(buildDir.length - 4)] + ['build', 'classes', 'debug']).join('/') sourceSets.testLocal.compileClasspath += files(buildDir) sourceSets.testLocal.runtimeClasspath += files(buildDir) } classpath = sourceSets.testLocal.runtimeClasspath } check.dependsOn localTest 

from: http://kostyay.name/android-studio-robolectric-gradle-getting-work/

Some more resources

The best articles I've found on this subject are:

+32
Nov 03 '14 at 15:18
source share

This is now supported in Android Studio, starting with the Android Gradle plugin 1.1.0, check this:

https://developer.android.com/training/testing/unit-testing/local-unit-tests.html

Sample application with local unit tests on GitHub:

https://github.com/googlesamples/android-testing/tree/master/unittesting/BasicSample

+4
May 16 '15 at 8:07
source share

For Android Studio 1.2 +, setting up a project for JUnit is pretty simple . Try following this guide:

This is the simplest part creating a project for JUnit:

https://io2015codelabs.appspot.com/codelabs/android-studio-testing#1

Follow the previous link until running the tests

Now, if you want to integrate with the instrumentation test, follow from here:

https://io2015codelabs.appspot.com/codelabs/android-studio-testing#6

+1
Sep 09 '15 at 0:50
source share

Please check out this tutorial on the official Android developers site. This article also shows how to create layouts for your testing.

By the way, you should notice that the dependency area for a simple JUnit test should be "testCompile".

0
Dec 09 '15 at 1:36
source share



All Articles