Ant build in Eclipse - android

I am trying to use custom build file in order to display the current git version in my Android application. I haven't used ant before and I have not really an idea how to use it. I read plenty of topics in SO and searched quite a lot in Google but I cannot figure it out. I don't really have the time to learn everything about ant but I need this thing running. At the bottom, you can find the code.
Current status
The file custom_rules.xml is imported in the build.xml created by Eclipse. The macrodef part is invoked but the targets not. I tried to change the External Tools Configurations, tab Targets but whenever I check a target (no matter in which ant file), I get a message:
Unknown argument: -pre-build
for example (when I put checkmark on -pre-build). I tried adding this line:
<import file="${sdk.dir}/tools/ant/build.xml" />
and defining sdk.dir but that doesn't change anything. What am I missing? As I said, I have no idea about ant and the only tutorial that helped me was this one.
Current code (custom_rules.xml)
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse.ant.import ?>
<project name="Custom build">
<macrodef name="git" taskname="#{taskname}">
<attribute name="command" />
<attribute name="dir" default="" />
<attribute name="property" default="" />
<attribute name="taskname" default="" />
<attribute name="failonerror" default="on" />
<element name="args" optional="true" />
<sequential>
<exec executable="git" dir="#{dir}" outputproperty="#{property}"
failifexecutionfails="#{failonerror}" failonerror="#{failonerror}">
<arg value="#{command}" />
<args/>
</exec>
</sequential>
</macrodef>
<target name="-pre-build">
<git command="rev-list" property="versioning.code" taskname="versioning">
<args>
<arg value="master" />
<arg value="--first-parent" />
<arg value="--count" />
</args>
</git>
<git command="describe" property="versioning.name" taskname="versioning">
<args>
<arg value="--always" />
</args>
</git>
<echo level="info" taskname="versioning">${versioning.code}, ${versioning.name}</echo>
<replaceregexp file="AndroidManifest.xml" match='android:versionCode=".*"' replace='android:versionCode="${versioning.code}"' />
<replaceregexp file="AndroidManifest.xml" match='android:versionName=".*"' replace='android:versionName="${versioning.name}"' />
</target>
<target name="-post-build" >
<replaceregexp file="AndroidManifest.xml" match='android:versionCode=".*"' replace='android:versionCode="0"' />
<replaceregexp file="AndroidManifest.xml" match='android:versionName=".*"' replace='android:versionName="0"' />
</target>
</project>

I just figured it out.
I renamed the targets to pre-build and post-build without -.
I went to External Tools Configurations and selected build.xml to the left. On the right, I went to the tab Targets, checked my two targets (in addition to the build target which already had a checkmark) and set the order to be pre-build, build, post-build.
I went to the project properties and I selected Builders on the left. I created a new builder using the build.xml file and having the three targets from the previous bullet point, in the same order. I placed this builder before the Java builder.
I removed the post-build target as it puts the version back to 0 and seems to do that earlier than I would like.
I am still not sure that this is the optimal solution. Also, the solution fails when there is no git versioning. I tried using this code for solving the issue but it didn't worked. Nevertheless, it is the best I could do and it helps me getting the info I need in the app.

Use Git executable with Argument --version and catch the output in a property for further usage, f.e. :
<project>
<exec executable="git" outputproperty="gitversion">
<arg value="--version"/>
</exec>
<echo>$${gitversion} => ${gitversion}</echo>
</project>
output :
[echo] ${gitversion} => git version 1.8.3.msysgit.0

Related

Using Ant how can I dex a directory of jars?

I have a directory full of jars (felix bundles). I want to iterate through all of these jars and create dex'd versions. My intent is to deploy each of these dex'd jars as standalone apk's since they are bundles. Feel free to straighten me out if I am approaching this from the wrong direction.
This first part is just to try and create a corresponding .dex file for each jar. However when I run this I am getting a "no resources specified" error coming out of Ant.
Is this the right approach, or is there a simpler approach to just input a jar and output a dex'd version of that jar? The ${file} is valid as it is spitting out the name of the file in the echo command.
<target name="dexBundles" description="Run dex on all the bundles">
<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${basedir}/libs/ant-contrib.jar" />
<echo>Starting</echo>
<for param="file">
<path>
<fileset dir="${pre.dex.dir}">
<include name="**/*.jar" />
</fileset>
</path>
<sequential>
<echo message="#{file}" />
<echo>Converting jar file #{file} into ${post.dex.dir}/#{file}.class...</echo>
<apply executable="${dx}" failonerror="true" parallel="true" verbose="true">
<arg value="--dex" />
<arg value="--output=${post.dex.dir}/${file}.dex" />
<arg path="#{file}" />
</apply>
</sequential>
</for>
<echo>Finished</echo>
</target>
Give this a go:
<target name="dexBundles" description="Run dex on all the bundles">
<apply executable="${exec.dx}" dest="${post.dex.dir}/" parallel="false">
<arg value="--dex"/>
<arg value="--output="/>
<targetfile/>
<srcfile/>
<fileset dir="${pre.dex.dir}" includes="**/*.jar"/>
<mapper type="glob" from="*.jar" to="*.dex"/>
</apply>
</target>
It looks like the ant apply task allows you to iterate over a file set without need for ant-contrib (specifically that page has an example that looks for *.c in a directory, compiles them, and renames them to *.o in a specified directory that should be directly applicable). Unfortunately, it looks like you'll lose the traceability provided by your echo messages.
For the record, I believe the error message is actually being generated by dx.bat not ant directly, but I am not certain, and I don't know why.
Hope that helps.
see the document of the "Ant apply task",it's said:“At least one fileset or filelist is required”
so,this line "no resources specified" is printed to notify u that to write some fileset or filelist.....
use "exec" instead.

Jenkins mobile air android packaging error

I've searched google and SO for solutions, but could not find any. I'm developing a mobile AIR app for android, and i use Jenkins as a local CI system. My project compiles fine, however, during the ADT packaging something goes wrong. I've copied the ADT packaging targets from the following examples:
http://blog.terrenceryan.com/using-ant-to-package-the-same-air-app-to-multiple-devices/
and
https://gist.github.com/630170
However, i am getting this output in Jenkins: http://d.pr/i/y2gJ
This is the packaging part in my build.xml file (with important property names and values used):
...
...
<property name="APP_NAME" value="Hightide"/>
<property name="ANDROID_HOME" value="${user.home}/../../../Supermaggel/SDKS/android-sdk-macosx" />
<property name="APP_DESCRIPTOR" value="${SOURCE_DIR}/${APP_NAME}-app.xml" />
<property name="SWF_FILE" value="${APP_NAME}.swf" />
<property name="OUTPUT_LOCATION_ANDROID" location="${BUILD_DIR}/android" />
<property name="OUTPUT_SWF_ANDROID" location="${OUTPUT_LOCATION_ANDROID}/${SWF_FILE}" />
<property name="OUTPUT_APK_ANDROID" value="OUTPUT_LOCATION_ANDROID/${APP_NAME}.apk" />
...
...
<!-- PACKAGE ANDROID -->
<target name="package-android">
<echo message="Packaging for Android"/>
<exec executable="${ADT}" dir="${OUTPUT_LOCATION_ANDROID}">
<arg line="-package"/>
<arg line="-target apk"/>
<arg line="-storetype pkcs12"/>
<arg line="-keystore ${KEYSTORE_ANDROID}" />
<arg line="-storepass ${STOREPASS_ANDROID}" />
<arg line="${APP_NAME}"/> <!-- output .APK -->
<arg line="${APP_DESCRIPTOR}"/> <!-- app descriptor location -->
<arg line="${OUTPUT_SWF_ANDROID}"/> <!-- output -->
</exec>
</target>
I am using Jenkins ver. 1.486, Flash Builder 4.6, AIR 3.3.
Can anyone point out what is going wrong during the packaging? any arguments missing or interpreted wrong?
I found out what caused it. The ADT cli tool gives exit code 2, which means something is wrong with the parameters... i spent hours looking at it, trying to figure out what was wrong. for ADT you need to pass in relative paths, not 'absolute' ones (or, relative from the project root.) so instead of ${PROJECT_ROOT}/packagedir/${APPNAME}.apk just use packagedir/${APPNAME}.apk or something similar, for all paths.

"java.lang.IllegalArgumentException: already added" when building a project which depends on library projects

Given
Commons - simple java project
AndroidLibrary1 - android library
AndroidLibrary2 - android library
AndroidProject - android project
And the projects have such references to each other:
AndroidLibrary1 -> Commons
AndroidLibrary2 -> Commons
AndroidProject -> AndroidLibrary1, AndroidLibrary2
Problem
When I build AndroidProject I get such error:
java.lang.IllegalArgumentException: already added: Lcom/test/Bar;
where "com.test.Bar" is a class from "Commons" project, that used by both AndroidLibrary1 and AndroidLibrary2.
Environment
Eclipse 3.7.1
android-sdk-windows_r15
Any ideas how to fix this?
EDIT:
Found related discussion.
After considerable amount of time and regex black magic I have found this solution:
<target name="-post-compile">
<macrodef name="dex-helper">
<element name="external-libs" optional="yes" />
<attribute name="nolocals" default="false" />
<sequential>
<!-- sets the primary input for dex. If a pre-dex task sets it to
something else this has no effect -->
<property name="out.dex.input.absolute.dir" value="${out.classes.absolute.dir}" />
<!-- set the secondary dx input: the project (and library) jar files
If a pre-dex task sets it to something else this has no effect -->
<if>
<condition>
<isreference refid="out.dex.jar.input.ref" />
</condition>
<else>
<path id="out.dex.jar.input.ref">
<path refid="jar.libs.ref" />
</path>
</else>
</if>
<if>
<condition>
<length string="${toString:out.dex.jar.input.ref}" trim="true" when="greater" length="0"/>
</condition>
<then>
<echo message="${toString:out.dex.jar.input.ref}" file="antler.tmp" />
<loadfile property="out.dex.jar.input.ref.fixed" srcFile="antler.tmp">
<filterchain>
<tokenfilter>
<replaceregex
pattern="(?<=;|^)[^;]+\\libs\\([^\\;]+)(?:;|$)(?=(?:(?<=;|^)[^;]+(?:;|$))*(?<=;|^)[^;]+\\\1(?:;|$))"
replace="" flags="g"/>
</tokenfilter>
</filterchain>
</loadfile>
<delete file="antler.tmp"/>
<path id="out.dex.jar.input.ref.fixed" path="${out.dex.jar.input.ref.fixed}"/>
</then>
<else>
<path id="out.dex.jar.input.ref.fixed" />
</else>
</if>
<dex executable="${dx}"
output="${intermediate.dex.file}"
nolocals="#{nolocals}"
verbose="${verbose}">
<path path="${out.dex.input.absolute.dir}"/>
<path refid="out.dex.jar.input.ref.fixed" />
<external-libs />
</dex>
</sequential>
</macrodef>
</target>
This is what you should add to your build.xml file before the <import file="${sdk.dir}/tools/ant/build.xml" /> line. In the case you have the same JAR in the libs folder in several of your projects, this code will remove the duplicate entries from the build system based on the file names.
Now, how this works
I will use the word "library" for JAR in libs folders and "library project" for the Android library projects on which other projects may depend. The problem is that when Android system builds projects with library projects, it just bundles all the libraries into one heap ignoring the fact that there may be duplicates. So we have to fix the paths.
So when the build gets to the point where the compilation is complete, we redefine the part which is responsible for converting Java code into DEX. The code above is exactly as in the Android build tools, except for the following part:
<if>
<condition>
<length string="${toString:out.dex.jar.input.ref}" trim="true" when="greater" length="0"/>
</condition>
<then>
<echo message="${toString:out.dex.jar.input.ref}" file="antler.tmp" />
<loadfile property="out.dex.jar.input.ref.fixed" srcFile="antler.tmp">
<filterchain>
<tokenfilter>
<replaceregex
pattern="(?<=;|^)[^;]+\\libs\\([^\\;]+)(?:;|$)(?=(?:(?<=;|^)[^;]+(?:;|$))*(?<=;|^)[^;]+\\\1(?:;|$))"
replace="" flags="g"/>
</tokenfilter>
</filterchain>
</loadfile>
<delete file="antler.tmp"/>
<path id="out.dex.jar.input.ref.fixed" path="${out.dex.jar.input.ref.fixed}"/>
</then>
<else>
<path id="out.dex.jar.input.ref.fixed" />
</else>
</if>
We have the unclean paths in out.dex.jar.input.ref, and our goal is to create paths without the duplicate entries (they will be stored in out.dex.jar.input.ref.fixed). Unfortunately we have to unload the path to a file, change it, and load it back, because ant for some weird reasons can't work with regex in properties (unless you are using external libraries like ant-contrib).
The regex which does the trick is (?<=;|^)[^;]+\\libs\\([^\\;]+)(?:;|$)(?=(?:(?<=;|^)[^;]+(?:;|$))*(?<=;|^)[^;]+\\\1(?:;|$)). This horrible mess of symbols matches the path which ends with libs\<something.jar> and has somewhere further another path which ends with <something.jar>. My regex uses Windows separator, so if you are under Linux or Mac OS X, you should change those \\ to the necessary separator or make the regex universal. Sorry, I was just in no mood to fix it having spent too much time on it already. If you want to check out how the regex works, you can do so on Regexr.
After we have removed the duplicates, we just have to load back the string to a new path, out.dex.jar.input.ref.fixed and use it to run dex. Hope my solution helps.

ANT build for Android Proguard obfuscation

Can anyone share with sample/simple obfuscation ANT task for Android? Provided that I do have complete APK and I need just pass *class hru Proguard and then prepare *.dex to build APK
I have found solution:
Get Proguard - copy proguard.jar into known directory (say MyProject/proguard)
Prepare proguard.cfg -describing what and how optimize/obfuscate. This process thoroughly described in Proguard's manual
Prepare following ANT's build.xml (or smth like this one) - great thanx to this guy
UPDATE complete build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="MyProject" default="zipalign" basedir=".">
<property name="target" value="android-8"/>
<!--property file="default.properties" /-->
<property name="encoding" value="UTF-8"/>
<!-- dirs -->
<property name="sdk.dir" location="Location of Android SDK"/>
<property name="proguard.dir" value="proguard" />
<property name="src.dir" value="src"/>
<property name="gen.dir" value="gen"/>
<property name="res.dir" value="res"/>
<property name="assets.dir" value="assets"/>
<property name="libs.dir" value="libs"/>
<property name="out.classes.unoptimized.dir" value="out"/>
<property name="out.classes.optimized.dir" value="out/optimized"/>
<!-- files -->
<property name="manifest.file" value="AndroidManifest.xml"/>
<property name="signed.apk" value="${ant.project.name}-signed.apk"/>
<property name="unsigned.apk" value="${ant.project.name}-unsigned.apk"/>
<property name="final.apk" value="${ant.project.name}.apk"/>
<property name="android.jar" value="${sdk.dir}/tools/platforms/${target}/android.jar"/>
<property name="unoptimized" value="unoptimized.jar" />
<property name="optimized" value="optimized.jar" />
<property name="proguard.config" value="${proguard.dir}/proguard.cfg"/>
<!-- tools -->
<property name="dx.jar" value="${sdk.dir}/platform-tools/lib/dx.jar"/>
<property name="aapt" value="${sdk.dir}/platforms/${target}/tools/aapt.exe"/>
<property name="zipalign" value="${sdk.dir}/tools/zipalign.exe"/>
<property name="jarsign" value="jarsigner.exe location is here"/>
<property name="keystore" value="Your key store is here"/>
<property name="keyalias" value="Your key alias is here"/>
<path id="android.antlibs">
<pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
<pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
<pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
<pathelement path="${sdk.dir}/tools/lib/apkbuilder.jar" />
<pathelement path="${sdk.dir}/tools/lib/jarutils.jar" />
</path>
<taskdef name="setup"
classname="com.android.ant.SetupTask"
classpathref="android.antlibs" />
<setup import="false"/>
<!--taskdef name="aaptexec"
classname="com.android.ant.AaptExecLoopTask"
classpathref="android.antlibs" /-->
<target name="clean" description="Removes output files created by other targets.">
<echo>Cleaning...</echo>
<delete dir="${out.classes.unoptimized.dir}" verbose="true" />
<delete dir="${out.classes.optimized.dir}" verbose="true" />
</target>
<target name="dirs">
<echo>Creating output directories if needed...</echo>
<mkdir dir="${out.classes.unoptimized.dir}" />
<mkdir dir="${out.classes.optimized.dir}" />
</target>
<!-- Compiles this project's .java files into .class files. -->
<target name="compile" depends="dirs"
description="Compiles project's .java files into .class files">
<echo>Compiling sources...</echo>
<javac encoding="${encoding}" target="1.6" debug="true" extdirs=""
destdir="${out.classes.unoptimized.dir}"
bootclasspathref="android.target.classpath"
includeantruntime="true">
<src path="${src.dir}" />
<src path="${gen.dir}" />
<classpath>
<fileset dir="${libs.dir}" includes="*.jar" />
</classpath>
</javac>
</target>
<target name="preobfuscate" depends="compile">
<echo>Preparing to obfuscation...</echo>
<jar destfile="${unoptimized}"
basedir="${out.classes.unoptimized.dir}"
includes="**/**"
excludes="optimized/**"
/>
</target>
<!-- Obfuscation with ProGuard -->
<target name="optimize" unless="nooptimize" depends="preobfuscate">
<echo>Proguard obfuscation...</echo>
<java jar="${proguard.dir}/proguard.jar" fork="true" failonerror="true">
<jvmarg value="-Dmaximum.inlined.code.length=16" />
<arg value="#${proguard.dir}/proguard.cfg" />
<arg value="-injars ${unoptimized}" />
<arg value="-outjars ${optimized}" />
<arg value="-libraryjars ${android.jar}" />
</java>
<unzip src="${optimized}" dest="${out.classes.optimized.dir}" />
<!-- Delete optimized jar (now unzipped into bin directory) -->
<delete file="${optimized}"/>
<delete file="${unoptimized}"/>
</target>
<target name="dex" description="Converting JVM bytecodes into Dalvik bytecodes" depends="optimize">
<echo>Converting bytecodes to Dalvik VM bytecodes...</echo>
<java jar="${dx.jar}" fork="true">
<arg line="--dex --verbose --output=${out.classes.optimized.dir}/classes.dex ${out.classes.optimized.dir}"/>
</java>
</target>
<target name="aapt" depends="dex" description="compile resources">
<echo>Packing resources...</echo>
<exec executable="${aapt}" logerror="true" osfamily="windows">
<arg line="p
-f
-M ${manifest.file}
-I ${android.jar}
-S ${res.dir}
-A ${assets.dir}
-F ${out.classes.optimized.dir}/${unsigned.apk}
-m -J ${gen.dir}"/>
</exec>
</target>
<target name="sign" depends="aapt" description="sign apk">
<input message="Please enter keystore password (store:${keystore}):"
addproperty="keystore.password" />
<echo>Signing apk...</echo>
<exec executable="${jarsign}" logerror="true" osfamily="windows">
<arg line="-verbose
-keystore ${keystore}
-storepass ${keystore.password}
-signedjar ${out.classes.optimized.dir}/${signed.apk}
${out.classes.optimized.dir}/${unsigned.apk} ${keyalias}"/>
</exec>
</target>
<target name="zipalign" depends="sign" description="zip align">
<echo>Aligning apk...</echo>
<exec executable="${zipalign}" logerror="true" osfamily="windows">
<arg line="-f
-v
4
${out.classes.optimized.dir}/${signed.apk}
${final.apk}"/>
</exec>
</target>
</project>
This ANT task has to be added to Eclipse's builders (Properties/Builders) tasks after Java builder and before Android package builder.
Press "Build All" (it's better to off Automatic Build check in Eclipse menu)
The Android build process first compiles Java source files (.java) to Java class files (.class), then converts these class files into Dalvik code (classes.dex), and finally packages this Dalvik code in an APK file.
ProGuard reads and writes Java class files, so it has to be inserted into this pipeline between the compilation step and the conversion step. It doesn't read or write Dalvik code itself, so it can't work on the APK file.
The Android SDK documentation on ProGuard discusses how to enable the obfuscation step in the Ant build for android-9. In short, you have to add a line "proguard.config=proguard.cfg" to the file default.properties, and then run "ant release".
Attention: barmaley's reply is from year 2011, and seem to be valid for Android SDK Tools version either 8 or 10.
I tried adapting this solution using Android SDK Tools version 18.1.1, but kept failing on the error:taskdef class com.android.ant.SetupTask cannot be found
Eventually, what I did was this:
rm build.xml
android update project -p .
If you don't have the SDK Tools in your PATH, you'll need to use the full path to the android tool, for example on Windows: C:\Android\sdk\tools
This created a fresh build.xml which is compliant with the current SDK Tools, and seem to automate a lot of the manual work that is described in barmaley's reply.
After that I was able to run ant release, which took care of building and obfuscating the result .apk file out of the box.
In order to automate obfuscation via ant, you'll need to:
Enable Proguard obfuscator (obviously)
Create an ant.properties file and fill it with the appropriate key.store params (see this SO reply for details).
The proGuard obfuscation process needs .class files so you can't launch an Ant before IDE build (.java) or after (.dex packed).
Have a look on this post where it's explained how add the proGuard step in your global Ant build:
http://www.androidengineer.com/2010/07/optimizing-obfuscating-and-shrinking.html
If you really want to use the IDEA build, you can try the following.
After the IDEA build unpack the apk with apktool.
Convert the .dex files to .class with dex2jar
Run proGuard as the previous post show you
Sorry that I don't attach you the links of apktool and dexjar but as I'm newbie I can't post more than one hyperlink.

Failing Android JUnit tests, not breaking my Ant script like I expect?

Failing JUnit tests, not breaking my Ant script like I expect?
My continuous integration server runs an Ant script, which calls something like:
/tests/ant run-tests
My JUnit tests run, but with errors:
run-tests:
[echo] run-tests-helper.
[echo] Running tests ...
[exec]
[exec] com.zedray.stuff.FooBarTest:....
[exec] com.zedray.stuff.FooBarTest:.....INSTRUMENTATION_RESULT: shortMsg=Some error in your code.
[exec] INSTRUMENTATION_RESULT: longMsg=java.security.InvalidParameterException: Some error in your code
[exec] INSTRUMENTATION_CODE: 0
The errors are OK, but my build script keeps going (eventually publishing my broken app to my testers - bad!). What I would expect is for the instrimentaiton to throw a build error, so my continuous integration server (TeamCity in this case) realises that something has gone wrong and reports a broken build. The "failonerror" is already set in the relevant macrodef, so I'm not sure what else I can do?
/tests/build.xml
Running tests ...
Any ideas/suggestions on how to fix this?
Regards
Mark
I did it another way, because I am using the ant test target that is in the Android build.xml file. This target prints to the standard out, so I captured stndout into a file then queried the file, using this result to fail my task.
<target name="run-acceptance-tests" depends="clean, debug, install" >
<property name="log.file" value="acceptance_tests_standard_out.txt" />
<!-- because we don't have control over the 'test' target (to check for passes an fails) this prints to standard out
we capture standard out into a file and query this to see if we have any test failures, using this to pass/fail our task -->
<record name="${log.file}" action="start" />
<antcall target="test" />
<record name="${log.file}" action="stop" />
<!-- do other stuff -->
<loadfile property="tests.output" srcFile="${log.file}" />
<echo>Checking for failures</echo>
<fail message="acceptance tests failed!" >
<condition>
<contains string="${tests.output}" substring="FAILURES" />
</condition>
</fail>
<echo>acceptance tests passed!</echo>
</target>
I had the same problem, and I ened up customize the "run-tests" target in my own build.xml like this, and there is no need to change the original android sdk test_rules.xml
<target name="run-tests" depends="-install-tested-project, install"
description="Runs tests from the package defined in test.package property">
<echo>Running tests ...</echo>
<exec executable="${adb}" failonerror="true" outputproperty="tests.output">
<arg value="shell" />
<arg value="am" />
<arg value="instrument" />
<arg value="-w" />
<arg value="-e" />
<arg value="coverage" />
<arg value="#{emma.enabled}" />
<arg value="${manifest.package}/${test.runner}" />
</exec>
<echo message="${tests.output}"/>
<fail message="Tests failed!!!">
<condition>
<contains string="${tests.output}" substring="FAILURES" />
</condition>
</fail>
</target>
Also was looking for some kind of standard solution for this. I wonder how do android guys develop, or they dont use teamcity and continuous integration? heard hudson has some plugin for android but I dont like hudson. anyway here is quick and dirty solution
replace contents in android-sdk-windows\tools\ant\test_rules.xml with:
<attribute name="emma.enabled" default="false" />
<element name="extra-instrument-args" optional="yes" />
<sequential>
<echo>Running tests ...</echo>
<exec executable="${adb}" failonerror="true" outputproperty="tests.output">
<arg line="${adb.device.arg}" />
<arg value="shell" />
<arg value="am" />
<arg value="instrument" />
<arg value="-w" />
<arg value="-e" />
<arg value="coverage" />
<arg value="#{emma.enabled}" />
<extra-instrument-args />
<arg value="${manifest.package}/${test.runner}" />
</exec>
<echo message="${tests.output}"/>
<fail message="Tests failed!!!">
<condition>
<contains string="${tests.output}" substring="FAILURES" />
</condition>
</fail>
</sequential>
there are two drawbacks
1) you dont see test output while tests are running until they failed (and the output is crippled somewhow)
2) its better to override this macro in your project
another option would of course be to ditch Ant in favor of Maven or Gradle. Both have Android plug-ins that properly fail the build when there are test failures.
Maven:
http://code.google.com/p/maven-android-plugin/
Gradle:
http://code.google.com/p/gradle-android-plugin/
running instrumentation tests has just been added to the Gradle Android plug-in, and is waiting to be merged back into the master repository, so there should be another release soon.
The ant JUnit task defaults to running all the tests. There are two solutions to this.
Easiest solution is to set the haltonerror property to true and the build will fail at the first test failure.
Slightly more involved (and my preference) is to set the failureProperty so that all the tests run. This lets you know how many tests fail instead of only the first test that fails. This requires more ant work because you need to add a line after your junit tests like this:
<fail message="tests failed" if="failureProperty"/>

Categories

Resources