Child pages
  • Building an Android app and test project
Skip to end of metadata
Go to start of metadata

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!

5 Comments

  1. Hi Torsten,

    To continue your article, I post an article on my blog, where I explain how to use QR code to test Android App built by Jenkins  on an Android device.

    http://jmlaboratory.blogspot.com/2012/02/qr-code-to-test-your-android.html

    Your comments are welcome!

    Regards,

    Jean-Marc

  2. In Findbugs paragraph there's a comment:

    Note, it may be necessary to add JARs your code depends on with additional "auxClasspath" elements, but I am not really sure.

    It is necessary for jars and library projects (otherwise Findbugs moans about missing classes needed for analysis), but it can be done a little easier than manually adding each jar to the auxClasspath. See this stack overflow thread for an enhanced findbugs target for ant. http://stackoverflow.com/questions/11720103/findbugs-for-android-project-with-libraries-in-ant-build

    Oh, by the way, in my target I've had to change ${android.jar} to ${project.target.android.jar} maybe that changed in a newer SDK, or something.

    Regards

    Marcin

  3. After having some trouble with Jenkins on my developement machine with "Error: Failed to generate emma coverage. Is emma jar on classpath?" here the solution:

    Reason for my trouble was that the apk on the emulator has a different signature when generated by eclipse or jenkins and installation from the other failed afterwards.

    Just add some ant targets before and after the findbugs and emma target:

    • target "uninstall" for each build.xml before findbugs,
    • target "clean uninstall" for each build.xml after emma target

    The clean up at the end gives a clean code basis in jenkins workspace and the bin and gen directories are gone (do you need them?).

    But be aware: your data on the emulator / device will be deleted (uninstalled) too - your app / tests should regenerate them.

    OK - I know that jenkins often runs on a designated machine / VM - but I like the reports and want to use them even when I'm sitting in the train (or outside if winter will end - hopefully soon - still snow in Hamburg) with my laptop.

    Regards
    Uwe

  4. This tutorials assumes that the structure of our project will be:

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

    However, at the Android Developers Website we can read the following:

    You can create a test project anywhere in your file system, but the best approach is to add the test project so that its root directory tests/ is at the same level as the src/ directory of the main application's project. This helps you find the tests associated with an application. For example, if your application project's root directory is MyProject, then you should use the following directory structure: MyProject/
    AndroidManifest.xml
    res/
    ... (resources for main application)
    src/
    ... (source code for main application) ...
    tests/
    AndroidManifest.xml
    res/
    ... (resources for tests)
    src/
    ... (source code for tests)

    It would be nice to update the tutorial to reflect the official method suggested by Google, since most of the Test Project will be following this structure.

    Regards,

    Enrique

    1. It has been a long time, but the tutorial is updated and it now describes the layout suggested by Google.

      It indeed has advantages and also makes it easier to set up the jobs in Jenkins.

      Kind Regards,

      Torsten