This post is not a complete guide about Robolectric or JBehave, it is just a quick guide to start to use TDD in a more productive way with Android. In order to complete the steps described in the Project Setup section you have to install in your system Eclipse Luna (you can use also different versions of Eclipse, Luna is the one I actually used for this tutorial) and Brew in order to easily install Maven on your system. The steps described in this post are assumed to be executed on OSX.
One of the biggest concerns when working with Android is the speed of the emulator. If you are lucky it takes from 40 to 60 seconds to run your app on the emulator or on a physical device, with the technology stack we are going to discuss in this tutorial it’s possible to significantly reduce this amount of time because you will be able to run the tests without waiting for the emulator. Last but not least using the Maven plugin Emma you can obtain accurate reports about your tests coverage outside and inside Eclipse.
The acronym TDD refers to the term Test-driven development. Test-driven development is a software development process that relies on the repetition of a very short development cycle where the developer first writes an automated test case that defines a desired feature, then produces the minimum amount of code to pass that test, and finally refactors the new code until the feature is not completely implemented. To successfully implement this process the cycle has to be fast and easy to execute. Well-written automated tests provide a working specification of your functional code and as a result tests effectively become a significant portion of your technical documentation. Most of the time developers use the term TDD to indicate unit testing. Unit testing is a software testing method by which individual units of source code, sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures, are tested to determine whether they are fit for use (wikipedia). Writing uint test first is a pattern well recognized in the modern software development industry. However apply blindly this pattern, in my opinion, is not the best approach because it can impact negatively your software design. When you focus only on testing then you try to avoid time consuming operations such as the access to the filesystem or to an external API mocking most of them and adding an unneeded layer of complexity. A probably better approach is to decide first what to test focusing on the automated tests that can improve the end user experience. An automated test can improve the end user experience because it can prevent that a new feature breaks an existing behavior of the software.
BDD and JBehave
The acronym BDD refers to the term Behavior-driven development. It shares the same process of TDD and in fact, also when using BDD, you let the tests to drive you during the development. The main difference between these techniques is what you test, in fact with BDD you test the behavior of a software in a specific scenario. Focusing on the behaviors of the software teams concentrate their efforts on identifying, understanding, and building valuable features that matter and that can be tested in a real scenario. When defining an automated test that describe the behavior of a software becomes natural to use a language that is not understandable just by developers, for instance take a look to this written using the Gherkin syntax
Feature: Withdrawal with balance
Given my bank account is in credit, and I made no withdrawals recently,
When I attempt to withdraw an amount less than my card’s limit,
Then the withdrawal should complete without errors or warnings
This test is understandable by developers, testers, project managers and product people, Behavior-driven development is one of the easiest way to ensure that all stakeholders are on the same page and understand how to build the right software rather than how to build the software right.
JBehave is an open source BDD framework originally written by Dan North, the inventor of BDD. It is strongly integrated into the JVM world, and widely used by Java development teams wanting to implement BDD practices in their projects. The main advantage of using JBehave is that it allows to write a test case using plain text that is then converted to a Java class. JBehave makes the transition from natural language style BDD-tests to Java methods incredibly quick also because it offers integration tools both for Eclipse and for IntelliJ IDEA.
Robolectric is a unit test framework that de-fangs the Android SDK jar so you can test-drive the development of your Android app inside the JVM on your workstation. One of the most important features of Robolectric in fact is that it mocks part of the Android framework contained in the android.jar file, this allows to run Android tests directly on the JVM with the JUnit 4 framework rather then waiting for the device emulator or for a real device. Robolectric is a highly configurable framework in fact it’s possible to specify which output to use, how to handle dependencies, etc. (for more details check the online guide) and it works with the most common automation tools like Maven or Gradle. In order to start using Robolectric with Maven you can clone this template project from GitHub, if you prefer to use Gradle then clone this template instead.
Maven is a build automation tool used primarily for Java based projects. In Maven an XML file describes the software project being built, its dependencies on other external modules and components, the build order, directories, and required plug-ins. Practically speaking the XML files contains:
- A detailed description about how the software is built
- An exhaustive list of the software dependencies
Installing Maven with Brew it’s pretty easy, check first that the system is updated by entering the following command in a terminal window
$ brew doctor (the worst case scenario is that installed brew formulas will be updated) and then type the command
$ brew install maven. In order to verify that Maven is installed correctly type the command
$ mvn --version and check that the installed version matches the most recent Maven release. In order to create a Maven project is enough to type the command
$ mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false. The project folder contains an XML file named
pom.xml, it is the core of a project’s configuration in Maven. It is a single configuration file that contains the majority of information required to build a project.
In order to start to use Robolectric, JBehave and Maven with Eclipse it’s mandatory to install the Android Developer Tools (i.e. ADT) plugin for Eclipse and eventually update the Android SDK. Once the plugin is installed Eclipse should be restarted and then it’s possible to download the last Android SDK or to add an existing SDK installation to the plugin. Robolectric currently supports the Android API Level 18 (i.e. Android 4.3 aka Jelly Bean), in order to run it correctly double check that the API is part of the current Android SDK installation. The setup of a Robolectric-JBehave-Maven Android project in Eclipse can be summarized as following:
- If not yet installed, install the Android for Maven Eclipse Plugin
- Install the JBehave Eclipse plugin
- Download the Robolectric JAR with all the dependencies available on sonatype.org and save it in a folder accessible from your Eclipse workspace
- Download the JBehave core 3.9.5 JAR available on mvnrepository.com and save it in the same folder that contains the Robolectric JAR
- Download the JBehave Maven plugin available on maven.org and save it with the previous downloaded JARs
- Clone the repository available on the Robolectric GitHub web site and execute in a terminal window the command
- Copy the
deckard-maven folder in the Eclipse workspace executing the following command in a terminal window
$ cp -R deckard-maven "path/to/the/eclipse-workspace" and eventually rename it into something more appropriate executing the following command
$ mv deckard-maven roboletric-getting-started in the Eclipse workspace directory
- Using a terminal window move to the folder that contains the project and execute the command
$ mvn clean install in order to verify that the configuration is correctly working
- Open Eclipse and import the existing Maven project ignoring the error messages
- Select the project, right click and open the
- In the
Properties panel select
Java Build Path then the tab
libraries and click
Add External JARs...; when prompted select the JARs previously downloaded click
open and then
- A message starting with “Plugin execution not covered by lifecycle configuration:” should be still in place in the
Problems tab in Eclipse, right click on it and select
Quick Fix; when prompted select the option
Permanently mark the goal ... as ignored in Eclipse built
- Select again the project, right click and from the
Maven menu item select the option
- Right click again on the project and from the
Run As... menu items select the option
Run Configurations and create a new
Maven Build one; specify in the goals
clean test and run the project
The project will run some tests without using the emulator, even more now it’s possible to use Eclipse as development IDE and run the tests from it or from the terminal. With this configuration it’s also possible to execute Emma (i.e.
$ mvn emma:emma)and other Maven plugins in order to get as much information as possible from the tests. In order to get all the benefits of this configuration create a new story using JBehave (i.e. right click on a folder,
other and then
New Story) and define a test case. Once done just right click on the story and from the
JBehave menu item select
Generate Steps; save the steps in the
src/test/java folder and run again the project. Fix the errors, execute the project and refactor again… welcome to the BDD development cycle!
In the next post I would like to address another common need that is to add Robolectric, JBehave and Maven as a test framework to an existing Android project without applying any significant change to the existing project. If you want to discuss this post or provide any suggestion for the next post let’s talk over twitter @giorgionatili, stay tuned and thanks for reading!
There are a lot of resources available on the web to improve your knowledge about Robolectric, JBehave, Maven, TDD and Android. The following links are a good starting point (this list was created in Jan 2015):