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.
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 Foundexception 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.)
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
My current solution isn’t perfect. But for now, I haven’t working solution for them. Hope it could be fixed in the future
AARis 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
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
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.