Start a new Android project this week, so I started to setup the development environment. To be honest, it is not an easy experience to me.
Features
Here are the features I got now:
- Unit test with Robolectric. (Very fundamental requirement)
- Unit tests are separated into an independent module. (Provide flexibility when project growing larger. And provide a more clear view of code organization)
- Running unit tests recognized by Android Studio/IntelliJ unit test plugin and debug UTs in IDE. (This is very important when diagnose failure UT)
- Running unit tests via CLI with
gradle wrapper
. (This is necessary requirement for CI servers) - Using resources in Robolectric test. (Avoid
Resource Not Found
exception in unit tests) - Test Android Annotation powered async implementation. (AA introduces new Async implementation, which is not supported by Robolectric by default)
- AssertJ core support. (Fest has been deprecated since no one is maintain it now.)
Versions
The major difficulties that I met are version compatibility, I almost tried all available version combinations to make them all works. Here are the versions that I uses
- Gradle: 2.1
- Groovy: 2.3.6
- Ant: 1.9.3
- JVM: 1.6.0_65 (Apple Inc. 20.65-b04-462)
- OS: Mac OS X 10.9.5 x86_64
- Android Studio: 0.8.11 (build AI-135.1446794)
- IntelliJ: IDEA 14 CE EAP, build IC-138.2458.8
- Android gradle plugin: com.android.tools.build:gradle:0.13.0
- Android ADT gradle plugin: com.neenbedankt.gradle.plugins:android-apt:1.4+
- Compile SDK version: 20
- Build tool version: 20.0.0
- Robolectric: 2.3
Known Issues
My current solution isn’t perfect. But for now, I haven’t working solution for them. Hope it could be fixed in the future
AAR
is not supported in Unit Test. (A tricky issue, I’ll explain more in detail later)- AssertJ-Android is not supported. (Cause by AAR support issue, alternative available.)
Project Structure and configurations
Here are the project structure:
Here are the contents
|
|
|
|
|
|
|
|
Why uses java
plug-in instead of android unit test
plug-ins
Well, Gradle DSL provides a lot of flexibility to developer. But it also brought a lot complexity to IDE implementation. To figure out project configuration, IDE need to parse and understand the gradle scripts. Not only DSLs provided by gradle but all stuff come with plug-ins. From IDE, this is almost an impossible mission. So IDE need to figure out a way to simplify the process, such as support a subset of DSL.
For Android project, IntelliJ has difficulties to understand the all variations of android unit test
plug-ins. So it is not easy to make unit test runnable from IDE. To solve the issue, you either try to teach IDE about the DSL by providing plug-in to IDE, or uses some languages that IDE understood.
I tried some plug-in available today, but none of them works for me. So I decide to use java
DSL, which IntelliJ understood natively. As a trade off, since java
gradle plugin doesn’t understand Android Library
, so it cannot import .aar
libries.
Besides I tried all android unit test
gradle plugins, I found all of them depends on android
gradle plugin. And android
plugin depends on AndroidManifest.xml
and some other stuff. It is wield to provide an manifest for your unit test.
So as the final solution, I uses java
plug-in, avoid using aar
in the test.
Why so complicate
Configurate an working Android project isn’t as easy as it sounds. Differ from iOS community, Google isn’t strong-minded as Apple. As a consequence that Android community is fragmented and lack of unified solution. There are tons of solutions available, but you might need to try them one by one to figure out which fits your requirement.
To make your tool chain, dependencies, IDE work together, compatibility is always your enemy. Even Google has to publish Version Compatibility Table to mitigate the pain.
What a mess!!!!!
References posts, plugins or template projects
Here is a list of things that I tried but failed to fit my requirement. List here since it might be helpful to other people.
- Android Gradle App with Robolectric JUnit tests
- tests-app-robolectric-junit template project
- deckard-gradle template project
- android-unit-test gradle plug in
- android-studio-unit-test-plugin android studio/intellij plugin
- robolectric-gradle-plugin
- robolectric-plugin