Filter Robolectric Android unit tests for faster verification
Customizing Robolectric Gradle plugin to run only a subset of unit tests

 Posted on Jan 31, 2015 by Ha Duy Trung

Robolectric is pretty much the de facto unit test framework for Android nowadays. It’s great, it’s fast (much faster than the out-of-the-box Android instrumentation test), and it gives you back joy of writing unit tests.

So you enjoy it so much that over the time you add more and more tests to your test suite that it no longer feels that fast anymore everytime you rerun it for verification? Well, it still needs to launch a VM to execute your tests after all. To improve this, you can make use of Robolectric’s Gradle plugin configuration to filter only tests that need to be rerun.

robolectric {
    include project.hasProperty("testFilter") ? "**/*${project.ext.testFilter}*Test.class" : '**/*Test.class'
    exclude '**/espresso/**/*.class'

    // other robolectric configs
}

Now when you run your Gradle test command, throw in a -PtestFilter=<filter> command line parameter to instruct Robolectric to run only the tests specified by your filter:

$ ./gradlew test -PtestFilter=Activity

The above command will execute all tests with class name following *Activity*Test pattern. No parameter will default to running all tests. A drawback I found with this approach is that if your pattern has no matches, Robolectric executes all tests instead of no test (since there are none).

Update (Mar 21st, 2015)

Latest Robolectric Gradle plugin with support for Android Gradle plugin 1.1.0 allows one to filter tests by running ./gradlew testDebug --tests='*.MyTestClass'

For more information, see Unit testing docs for Android Gradle plugin.

Another tip to speed up your test run is to tell Robolectric to parallelize your test run using more processes if possible:

robolectric {
    // Specify max number of processes (default is 1)
    maxParallelForks = 4

    // other robolectric configs
}

Separate debug activities from your live Android analytics with Gradle
Utilizing Gradle build types to inject different configurations for separating analytics tracking for different build types

 Posted on Jan 29, 2015 by Ha Duy Trung

Gradle plugin for Android is the official build tool for Android, and is getting better everyday with new features allowing you to customize your build process more and more. One of its feature is allowing one to inject resources that can have different values per build type/product flavor. We can utilize it to separate analytics data for development and production.

In your build.gradle:

android {
    defaultConfig {
        applicationId "<appId>"
        minSdkVersion 9
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
        resValue "bool", "debug", "true"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
            zipAlignEnabled true
            resValue "bool", "debug", "false"
        }

        <other build types>
    }
}

This script uses resValue to set debug bool resource to true by default for all build types, and overriden by release build type. We can then access this bool resource from Java code to configure Google Analaytics based on debug value (I did it in my Application class in this case)

public class Application extends android.app.Application {
    @Override
    public void onCreate() {
        super.onCreate();
        if (getResources().getBoolean(R.bool.debug)) {
            GoogleAnalytics.getInstance(this).getLogger().setLogLevel(Logger.LogLevel.VERBOSE);
            GoogleAnalytics.getInstance(this).setDryRun(true);
        }
        GoogleAnalytics.getInstance(this).newTracker(R.xml.ga_config);
    }
}

Update (May 12th, 2015)

From Google Play Serivces 7.0.3, Logger interface has been deprecated and one can only configure log level per device, by using adb shell setprop log.tag.GAv4 <log-level>

For more information, see API documentation.

With the above setup, Google Analytics will show verbose GAV4 logging but not sending real hit to Google Analytics server except for your release builds, which I assume are only used for production. More advanced settings can be applied in similar fashion to configure different GA tracker per build type, or some other setups based on your needs.