Jenkins : Building an Android app and test project

Introduction

If you have an Android app project including a test project in Eclipse and you would like to use Jenkins for Continuous Integration and have Checkstyle, FindBugs and Emma coverage trends - this is how it should work.

Assumptions

You have an Android app including a test project in Eclipse. For this document, let's assume the app project is called "android-app" and the test project "test" is located inside "android-app", and that your Android SDK is installed in "/home/joe/android-sdk".
This document also assumes that you are checking in your projects to a version control system like Subversion, and that you are checking them out in Jenkins from there.
The procedure described here should work with SDK 14 or above (last tested with SDK 23).

The directory tree should look like

/home/joe/workspace
/home/joe/workspace/android-app
/home/joe/workspace/android-app/test

Assuming this directory structure then the commands below would be executed from /home/joe/workspace

Set up Ant

  • Install Ant if you don't have it already
  • In your Eclipse workspace, run the following command to set up Ant for the app project:
    android update project -p android-app
    
  • Then run this command to set up Ant for the test project. Note that the path given to -m must be the relative path to the project under test, seen from the test project, not the workspace:
    android update test-project -m ../ -p android-app/test
    
  • If you have any library projects that need to be set up for and use this
    android update lib-project --target "Google Inc.:Google APIs:13" --path JakeWharton-ActionBarSherlock/plugins/maps
    
  • Refresh the projects in Eclipse
  • Note: The files "local.properties" and "ant.properties" contain local configuration, like the location where your Android SDK is installed. Since this location can be different on build machines, this file should not be checked in to version control. So it is recommended to add them to the "Ignored Resources" in Eclipse right away.

    The file "ant.properties" in the test project contains the relative path "tested.project.dir=../", so it is okay to check it in to version control. If you don't want to check it in anyway, you can set the property in the Jenkins configuration of the test job under the "Advanced" settings of "Invoke Ant".

  • The files "project.properties" are required and must be checked in to version control.
  • Test if you can build the app project in "android-app" with
    ant clean debug
    
  • Make sure that you have a (virtual) device (only one at a time!) running, and see if you can build the test project and run the tests in "android-app/test":
    ant clean emma debug install test
    

    If you receive an error like "Failed to generate emma coverage. Is emma jar on classpath?", try to build the test project with "ant all clean emma debug install test", this might fix it.

  • This will take a bit longer. Eventually, you should find a "coverage.html", "coverage.xml" and "coverage.txt" in the "bin" folder of your test project, containing the test coverage.

    If you can only find a "coverage.html" in your project (probably in a "coverage" folder), follow the steps in the "Emma" section below, otherwise skip it.

Emma

This section can be skipped if the build creates a "coverage.html", "coverage.xml" and "coverage.txt" in the "bin" folder of your test project, which should be the case with at least SDK 22 or later.

If you want to build your projects in Jenkins and use the Emma plugin to see the test coverage and trend, you cannot use the "coverage.html" file as it currently is generated by the "coverage" Ant task and you have to change it to create a "coverage.xml" instead:

  • Go to your Android SDK installation, and open the file "tools/ant/build.xml", copy the complete "test" target and paste it in the "build.xml" of the test project, before the import of build.xml, so before the comment starting with "Import the actual build file". There is more information on how to customize targets in that comment.
  • Change the version-tag from "1" to "custom" to avoid the file being overwritten by future runs of "android update project":
    <!-- version-tag: custom -->
    
  • Note: Eclipse might complain about your build file. Since I didn't know how to get rid of these errors and warnings, I just set "Ignore all buildfile problems" in the "Ant Editor settings" in Eclipse's preferences.
  • In the copied "test" target in your build.xml, make the following changes:
  • Change
    <html outfile="coverage.html" />
    
  • to
    <html outfile="coverage.html" />
    <xml outfile="coverage/coverage.xml" />
    
  • Adjust the last "echo" message accordingly (just for the sake of correctness):
    <echo>Saving the report file in ${basedir}/coverage/coverage.html and ${basedir}/coverage/coverage.xml</echo>
    
  • When you now run "ant clean emma debug install test" again, you should have a coverage.xml file, ready to be used by Jenkins!
  • Note: The Emma XML report does not provide "highlighting individual source line coverage states" as the HTML report does. So we make both reports. See the ANT section in the emma manual http://emma.sourceforge.net/userguide_single/userguide.html

Checkstyle

  • If you don't already have Checkstyle installed, download the JAR from http://sourceforge.net/projects/checkstyle/. Let's assume that you install it to "/usr/lib/checkstyle".
  • Add the location of your Checkstyle installation to the "ant.properties" file in your app project:
    checkstyle.jar=/usr/lib/checkstyle/checkstyle-all.jar
    
  • Place "google-checks.xml" or your own checkstyle configuration in the root of the app project
  • Add the following taskdef and target to the "build.xml" of your app project:
    <taskdef classpath="${checkstyle.jar}" resource="checkstyletask.properties" />
    <target name="checkstyle">
    	<mkdir dir="reports" />
    	<checkstyle config="google_checks.xml">
    		<formatter type="xml" tofile="reports/checkstyle-result.xml"/>
    		<fileset dir="src" includes="**/*.java"/>
    	</checkstyle>
    <target>
    
  • Change the version-tag from "1" to "custom" to avoid the file being overwritten by future runs of "android update project":
    <!-- version-tag: custom -->
    
  • To create a Checkstyle report, run your app project like this:
    ant clean debug checkstyle
    
    You should get a folder "reports" containing a "checkstyle-result.xml" file.
  • You might want to add the "reports" folder to the version control "Ignored Resources" as well.

FindBugs

  • If you don't already have FindBugs installed, download the .zip or .tar.gz from http://findbugs.sourceforge.net/downloads.html. Let's assume that you install it to "/usr/lib/findbugs".
  • Copy "lib/findbugs-ant.jar" from your FindBugs installation to the "lib" folder of your Ant installation.
  • Add the location of your FindBugs installation to the "ant.properties" file in your app project:
    findbugs.home=/usr/lib/findbugs
    
  • If you want to exclude FindBugs warnings for the R.java generated source file, create a file "findbugs-exclude.xml" in your app project folder with the following content:
    <?xml version="1.0" encoding="UTF-8"?>
    <FindBugsFilter>
    	<Match>
    		<Class name="~.*\.R\$.*"/>
    		<Bug code="Nm"/>
    	</Match>
    </FindBugsFilter>
    
  • Add the following taskdef and target to the "build.xml" of your app project:
    <taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"/>
    <target name="findbugs">
    	<mkdir dir="reports" />
    	<findbugs home="${findbugs.home}" output="xml" outputFile="reports/findbugs.xml" excludeFilter="findbugs-exclude.xml">
    		<auxClasspath path="${project.target.android.jar}"/>
    		<class location="${out.dir}" />
    	</findbugs>
    </target>
    
  • Change the version-tag from "1" to "custom" to avoid the file being overwritten by future runs of "android update project":
    <!-- version-tag: custom -->
    
  • To create a FindBugs report, run your app project like this:
    ant clean debug findbugs
    
    You should get a folder "reports" containing a "findbugs.xml" file.
  • Note, it may be necessary to add JARs your code depends on with additional "auxClasspath" elements, but I am not really sure.
  • If you don't want to use the "findbugs-exclude.xml" described above, you have to remove the "excludeFilter" attribute.
  • You might want to add the "reports" folder to the version control "Ignored Resources" as well.

Jenkins

Create and configure the app project

Create a "Freestyle project" for the app project.

  • Configure the "Source Code Management" to check out the app project
  • Add an "Invoke Ant" build step and set "Targets" to
    clean debug checkstyle findbugs
    
  • Under "Advanced", add the following properties and adjust the paths according to the Android SDK, Checkstyle and FindBugs installation location of the machine where Jenkins is running on:
    sdk.dir=/home/joe/android-sdk
    checkstyle.jar=/usr/lib/checkstyle/checkstyle-all.jar
    findbugs.home=/usr/lib/findbugs
    
  • Under "Post-build Actions" check "Publish Checkstyle analysis results" and "Publish FindBugs analysis results". It should not be necessary to make any settings there.
  • You should now be able to build the project, and the Checkstyle and FindBugs trend should be visible after at least 2 successful builds.

Configure the test project

Create the test project using "Copy existing Item" by copying from the app project. Change the description

  • "Source Code Management" should stay the same - check out the app project
  • Add an "Invoke Ant" build step and set "Targets" to
    clean emma debug install test
    

    For the SDK 14 use "clean emma debug" and a second task "ant emma installt test" http://code.google.com/p/android/issues/detail?id=20997
    Also fix your build.xml as described here: http://code.google.com/p/android/issues/detail?id=20979&can=1

  • Under "Advanced", specify the relative path to the "Build File" of the test project:
    test/build.xml
    
  • The "Properties" under "Advanced" should be the same as for the app project.

    If you did not check in the "ant.properties" of the test project including "tested.project.dir=../", you can add this property here

  • Delete any "Post-build Actions" like Checkstyle and FindBugs that you don't want to run in the test build
  • Under "Post-build Actions", check "Record Emma coverage report". In "Folders or files containing Emma XML reports", I filled in:
    **/bin/coverage*.xml
    

    If coverage files are placed in a "coverage" folder in your project, the path should be

    **/coverage/coverage*.xml
    
  • If you want to view the HTML coverage reports from within the Jenkins job, add "Publish HTML reports" to "Post-build Actions" and set test/bin or test/coverage as "HTML directory to archive" and coverage.html as "Index pages". The text set as "Report title" is used for the link in the job menu to the HTML reports.
  • You should now be able to build the project and the Emma coverage trend should be visible after at least 2 successful builds.

Happy building!