Skip to main content

Robolectric setup in Android Studio 1.0

These days I have been using Android Studio v1.0 and I want to do test using Robolectric, which give you more freedom for unit testing in Android. You can perform your test without emulator running. But I have faced setting problems even though the website looks like they're explaining well about how to setup the configuration. I blamed my brain but I found out there were missings for Android Studio gradle build and I had to google it a little bit more.
I am not familiar with Gradle yet, but Android Studio uses Gradle as default build tool and Gradle seems to be a quite great build tool.
There are two 'build.gradle's for Android Studio project. These are the main file for build configuration. One of them(a) is in your project folder is for global setting and the other one(b) in the 'app' folder is just for your app.

myproject
 - build.gradle (a)
 - app
   - build.gradle (b)

For the right setup, we need to touch a few things. 1) Installation 'Android Studio Unit Test' plugin.
2) Setting for JC&K Gradle plugin(depricated since Android Gradle version 1.1)
3) Dependencies configuration
4) Open the "Build variants" tool window (on the left) and change the test artifact to "Unit tests".
5) Write unit test using JUnit and RobolectricTestRunner

Let's get over one by one. I'm using Android Studio 1.0.1 with Macbook pro and my explanation is based on that. (Sorry for Windows users)

1) Installation 'Android Studio Unit Test' plugin In your Android Studio, go to Android Studio -> Preferences... -> Plugins. Click Browse repositories button on the bottom and search 'Android Studio Unit Test'. Install it.

2) Setting for JC&K Gradle plugin Open myprject/build.gradle. Add 'classpath 'com.github.jcandksolutions.gradle:android-unit-test:2.1.1' in dependency section. Now, myproject/build.gradle looks like the following:

Since version 1.1 of the Android Gradle plugin, unit tests in JVM are natively supported. This plugin has been deprecated from https://github.com/JCAndKSolutions/android-unit-test#deprecation-notice

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.0.0'
        classpath 'com.github.jcandksolutions.gradle:android-unit-test:2.1.1'
    }
}
allprojects {
    repositories {
        jcenter()
    }
}

And then, we need to apply the Gradle plugin in our app’s build.gradle file. Add 'apply plugin 'android-unit-test' after buildType and dependencies section.

Since version 1.1 of the Android Gradle plugin, you don't nee android-unit-test plugin any more.

apply plugin: 'com.android.application'

android {...}

apply plugin: 'android-unit-test' 

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

}

3) Dependencies configuration Now, we need to setup dependencies. Roboreltric uses JUnit4 as a test framework, so we need JUnit , Robolectric as dependencies and other things like below:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.0'
    testCompile 'junit:junit:4.12'
    testCompile 'org.mockito:mockito-core:1.9.5' //optional
    testCompile 'org.robolectric:robolectric:3.0-rc2'
    testCompile 'com.squareup:fest-android:1.0.8' 

}

I am using appcompat library to use material design in lower versions and I setup its version to 21.0.0. It is different Android Studio gives you a bit different version when you create API 21 project.
Now, it should look like this:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion '21.1.2'

    defaultConfig {
        applicationId "your.package.name"
        minSdkVersion 21
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.0'
    testCompile 'junit:junit:4.12'
    testCompile 'org.mockito:mockito-core:1.9.5'
    testCompile 'org.robolectric:robolectric:3.0-rc2'
    testCompile 'com.squareup:fest-android:1.0.8'

}

4) Open the "Build variants" tool window (on the left) and change the test artifact to "Unit tests".

5) Write unit test using JUnit and RobolectricTestRunner

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.model.InitializationError;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

@Config(emulateSdk = 18)
@RunWith(value = RobolectricTestRunner.class)
public class MyFristRoboreltricTest {
 @Test
    public void testMethod1(){
  assertTrue( false)
 }
}

If you give emulateSdk = 21, it will give error when you run the test. It look like Roboreltric does not support above API 21 yet. So, you have setup emulateSdk for @Config annotation under 21.

There is last thing to perform unit test successfully. Android Studio 1.0 create test folder your_project/app/src/androidTest as default. But Robotinum does not recognise the folder. You can change your app build.gradle to set test folder:
sourceSets {
   androidTest {
       setRoot('src/androidTest')
   }
}

But unfortunately, it did not work. Weirdly, when I change the test folder androidTest to test and commented the sourceSets section, it worked charm. I haven't looked into Android Studio Gradle source yet, but I can guess test path may be hardcoded.

You might need to set Android Studio view mode to Project to see the project directories. It is app by default.

More links:
http://stackoverflow.com/questions/29714750/android-studio-1-1-0-cannot-setup-robolectric
http://tools.android.com/tech-docs/unit-testing-support

Comments

Post a Comment

Popular posts from this blog

Apply Kotlin DataBinding to Android Studio Generated Main Activity

I posted how to setup Kotlin and DataBinding in Android Stuido in the last blog (http://marksunghunpark.blogspot.com.au/2017/04/kotlin-binding-library-setup-in-android.html). In this post, I am going to how to use DataBiding in the MainActivity when you create a navigation drawer project from Android Studio templates. Layouts You will have four layouts in app/src/res/layout folder: app/src/main/res/layout/activity_main.xml app/src/main/res/layout/app_bar_main.xml app/src/main/res/layout/content_main.xml app/src/main/res/layout/nav_header_main.xml And activity_main.xml contains all other layout using include layout. You need to have tag in activity_main.xml , app_bar_main.xml and content_main.xml . If you don't have the tag, Binding library cannot recognise the sub layouts properly. Binding library doesn't support toolbar and navigation drawer yet, so you can use using BindingAdapter if you want to use binding library.(But I'm gong to skip this part for simplici

How to test AsyncTask in Android

In Android, test is not as easy as any other platform. Because Android test cannot be run without emulator. Particulary when it comes to AsyncTask or Service, it is difficult to test because they are different type of thread and hard to check their result. Then, how can we ensure the result of AsyncTask valid? AsyncTask is a thread and an asynchnorous as the name means. So, we need to wait for it finishes its job and need to capture the event. Then, when it happens in AsyncTask. It can be one of onBackground() and onPostExecute() methods. It doesn't matter you use onBackground() or onPostExecute() but I prefer onPostExecute(). Anyway, we can test an AsyncTask if we can hook it. Then, how can we hook it? For that, we can use callback pattern. But we need to delay main thread to wait for the AsyncTask's job done because we want to check the result. So the structure for the test would be like: 1. Create AsyncTask A 2. Injection a callback into A 3. Wait until A finish 4.

Let's start Lambda in Android

In Android programming, I think Java & J2EE programming are not that different, we developers put many boiler plate code particularly when we use anonymous instances. Example1. Simple example button1.setOnClickListener(new OnClickListener(){ @Override public void onClick(View view){ //Do something } }); In the above example, what we really need is inside of onClick() method. Other code is actually decorations and we don't want it. How about we can pass just onClick method body as a parameter of setOnClickListener method like below? button1.setOnClickListener(view->{ //Do something }); That's what we have exactly wanted. We can use the code style in Java 8. I think you already might know about Java 8 Lambda but there is no official support for Java 8 in Android 8. It would be awesome we can use it in Android and there is a way to be able to use Lambda in Android as well. You can refer my previous blog to setup RetroLambda in Andro