Upgrading Lost to Robolectric 3.2

shh…” by swimfinfan licensed under CC BY-SA 2.0

Today I upgraded Lost (Mapzen’s open source Android location services project) to use the latest release of Robolectric (version 3.2.1).

Lost relies heavily on the Android framework location classes especially LocationManager. It also starts a background Service and maintains a connection using Context.bindService(...).

When dealing with functionality such services as location updates it would be technically challenging and possibly not a great use of time to write an abstraction layer for the Android framework. Therefore we use Robolectric to facilitate testing of this library.

Performance

The following stats were compiled in decidedly unscientific fashion running a handful of builds before and after the upgrade. The results however were rather consistent after the initial build.

Currently the project has 334 unit tests most written using Robolectric and some pure JUnit.

First I ran the tests in Android Studio using a JUnit run configuration for all tests in package similar to what you would do during development. Second I ran the tests on the Command Line locally using ./gradlew clean testDebug which is similar to what you might do in a CI environment.

v3.1.2

Android Studio ~17 seconds
Command Line ~22 seconds

v3.2.1

Android Studio ~23 seconds
Command Line ~29 seconds

The drop in performance is somewhat concerning but I know active efforts are underway to improve speed and memory consumption in the next release.

Other changes

  • All instances of the deprecated class RobolectricGradleTestRunner needed to be replaced with RobolectricTestRunner since the prior was completely removed in version 3.2.
  • ShadowLocation is now deprecated but we did not really depend on this implementation preferring to use our own mock Location objects with Mockito.
  • A fix I had submitted to resolve registration of duplicate listeners with the ShadowLocationManager made it into this release which is great. Unfortunately we still rely on a local copy of the shadow location manager in Lost because the method requestSingleUpdate(...) still has no shadow implementation. Writing a working shadow for this method and contributing it has been on my TODO list for a while now!
  • Finally we had one failing test after the upgrade. The original version of this test used two PendingIntents that wrapped the same Intent to start a TestService to register for two sets of location updates. Due to a fix in the equals method for ShadowPendingIntent the location updates were correctly only registered once so the solution was to use a different Intent for a different Service when requesting the second set of location updates.

Conclusion

All in all the upgrade was rather painless. Testing this type of library project that is tightly tied to the Android framework would not be possible without Robolectric so for that I am thankful.

If you currently have a project using Robolectric 3.1.x I would encourage you to upgrade. If you do let me know how it goes in the comments.