Applying Test-Driven Development to Android Development
Test-Driven Development (TDD) is a cornerstone practice for agile development teams. TDD provides the benefit of verifying that your code is correct up front while forcing you to use your own APIs. This leads to better design and fewer bugs in the software. In addition, because unit tests can be run in an automated fashion through continuous integration, regression defects are caught immediately. With Android development now being performed in the corporate space by large teams, agile practices are a necessity. Yet, Android development poses some significant challenges when it comes to following a TDD approach.
Android classes make assumptions about their environment of execution.
Components within the Android SDK make assumptions about the availability of other components and services. This creates a challenge for writing tests that can execute outside the Android environment. In general, we want tests that can be developed and executed efficiently. And having to deploy to an Android device to execute a test is not an efficient process.
Final classes make the use of mock objects challenging.
Wikipedia provides great a definition of mock objects:
Mock objects simulate the behavior of complex, real (non-mock) objects and are therefore useful when a real object is impractical or impossible to incorporate into a unit test.
This sounds like a great solution to simulate the behavior of the Android components, but it is not possible with much of the Android SDK. Java provides the keyword final, which when used at a class level, indicates that the class cannot be further extended. Many of the classes in the Android SDK classes are defined as final, limiting the usefulness of this approach.
Emulation is slow and impractical for a large number of tests.
An additional option is the development of tests that run within the Android emulator. The Android SDK provides library components for achieving this, but the test execution is slow. When writing a large application, the speed of test execution is critical to ensure a reasonable timeframe for build execution. A build that executes for longer than two minutes is considered excessive. Waiting several minutes for tests to execute negatively impacts a team's velocity. We need a different approach.
The Robolectric framework supports test-driven development.
Robolectric is a framework for unit testing with Android that provides the best of both worlds. The framework intercepts calls to Android classes through "shadow classes," providing testable behavior for a significant portion of the Android SDK. This all works without the need for emulation which provides the quick turnaround a developer needs when writing tests, writing code, and refactoring.
The framework even provides excellent support for extension, allowing you to customize Android SDK behavior to your own needs. So if your organization is embarking on an Android project, have a look at Robolectric. It will enable your team to follow the agile test-driven development practice—even with the challenges presented by the Android SDK.