The last weeks I had the chance to dive deeper into unit testing of an Android application. The solution we are using is Robolectric. It is an interesting and promising framework since it does not need an emulator but just runs as standard junit test. The tests we have been able to write and run with it are great. You can even create an instance of an activity, inflate the UI from layout files and check the state of single views. Or you can send a broadcast intent and check if it has been received.
Of course, Robolectric does not create a real UI for the tests. The way Robolectric allows testing of Android applications, works by intercepting the creation of instances of Android classes and provides some kind of proxy objects for them (so called Shadows). This way, the Robolectric developers have been able to rewrite parts of the platform’s behaviour, emulate the logic of a lot of classes and internally keep track of the state of the objects.
While this allows for efficient unit and integration testing without starting an emulator, it is clear that Robolectric tests do not replace testing on real Android devices or emulators with different OS versions. There are a few reasons for this:
- The code just emulates the logic the Robolectric developers have implemented. For the most common use cases, this works well, but you find missing/limited functionality quite quickly. This will improve over time. Nevertheless, one has to be aware of the fact, that not the real Android classes are used and the behaviour can be different from the Robolectric classes.
- The Robolectric framework does not emulate the real lifetime of an whole application. E.g. it will not start an activity or a service on its own. Also, it does not emulate the lifecycle of activities. This is by purpose, since it anyway is meant only for testing single units of the app. Of course, you can check which intent is being sent from an activity, which allows for testing the correct behaviour.
- There are also general limits to this concept. E.g. when your app is not based on the standard View classes, but uses OpenGL, this can not be tested with Robolectric. I would say, all cases where real hardware is involved, can not be tested.
In summary, Robolectric allows efficient testing of a lot of use cases of an Android application. It is certainly not enough to make sure it will run on all devices. But it already provides a way to cover a lot of use cases of standard Android applications and make sure that the single components of your app behave correctly.
One thing that is heavily missing is better documentation, though. Without having the source code of Robolectric available and checking how it is implemented or looking at the unit tests of Robolectric itself, I would have not been able to figure out how some things are expected to work.
Therefore, I will try to collect here some howtos and hints for Robolectric in the coming weeks.
My other articles about Robolectric might also be interesting for you.