Skip to content

Instantly share code, notes, and snippets.

@roottony
Last active August 29, 2015 14:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save roottony/44f74aec79dd16c61819 to your computer and use it in GitHub Desktop.
Save roottony/44f74aec79dd16c61819 to your computer and use it in GitHub Desktop.
Android Studio 0.9.1 with Robolectric

README

Allows running Robolectric tests directly from the Android Studio.

Supported versions

This script works with com.android.tools.build:gradle:0.14.0 and Android Studio v0.9.1

Instructions

Robolectric setup

Add robolectric to your project as described here:
https://github.com/robolectric/deckard-gradle.
Complete all steps before "IntelliJ / Android Studio Support".

build.gradle

  1. Place robolectric-iml.gradle near the build.gradle file.
  2. Apply it after android plugin

Android Studio

Setup your default JUnit configuration:

EditConfigurations ... -> Defaults -> JUnit

  1. Remove Make from Before launch section
  2. Add new Before launch entry, Run external tool
  3. Give it any name
  4. Program: ./gradlew
  5. Parameters: --daemon --offline testDebugClasses
  6. Working directory: full-path-to-directory-of-gradlew-file
  7. Apply everything
  8. Restart Android Studio

Now you can run your robolectric tests from the IDE.

FAQ

Q: Could we launch gradle task, not external tool?
A: Yes, but in this case gradle task is run simultaneously with the tests (for some strange reason), which can cause some race conditions.

Q: Could we use macros instead of hardcoded project path?
A: Yes, but for me it broke after first build.

Credits

The script is based on this script. Many thanks, Nico!

// Place robolectric-iml.gradle near build.gradle
apply plugin: 'com.android.library'
apply from: 'robolectric-iml.gradle'
task prepareImlForTests() {
def imlFile = file(project.name + ".iml")
def TEST_CLASSES_PATH = 'file://$MODULE_DIR$/build/test-classes'
// Will work on 3rd invocation only, but it's "beta than nothing"
inputs.file(imlFile)
outputs.file(imlFile)
doLast {
project.logger.info "Updating ${imlFile} for robolectric tests"
try {
Node parsedXml = new XmlParser().parse(imlFile)
Node componentNode = parsedXml.component[1]
Node outputTestNode = componentNode.'output-test'[0]
def rewrite = false
// Move SDK entry to the end of the node
Node androidSdkEntry = componentNode.orderEntry.find { it.@type == "jdk" }
if (androidSdkEntry != null) {
componentNode.remove(androidSdkEntry)
componentNode.append(androidSdkEntry)
rewrite = true
}
// add 'output-test' property if not present
if (outputTestNode == null) {
new Node(componentNode, 'output-test', ['url': TEST_CLASSES_PATH])
} else {
if (outputTestNode.attributes['url'] != TEST_CLASSES_PATH) {
outputTestNode.attributes = ['url': TEST_CLASSES_PATH]
rewrite = true
}
}
if (rewrite) {
def writer = new StringWriter()
new XmlNodePrinter(new PrintWriter(writer)).print(parsedXml)
imlFile.text = writer.toString()
}
} catch (FileNotFoundException e) {
// iml not found, common on command line only builds
}
}
}
// always do the addtest on prebuild
project.afterEvaluate {
preBuild.dependsOn prepareImlForTests
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment