I have a Java project with some unit tests written using JUnit. Recently some new unit tests have been added that are written in groovy (also using JUnit) as it's easier to make those
more expressive and generally easier to read. It also allows us to use the spock framework.
The project is build and tested with ant.
Before the groovy classes were added unit tests were run using the following ant task:
<target name="test" depends="test-compile">
<junit printsummary="yes">
<classpath>
<path refid="test.classpath"/>
</classpath>
<formatter type="plain"/>
<batchtest fork="yes" todir="${test.dir}/report">
<fileset dir="${test.dir}/unit" includes="**/*.java"/>
</batchtest>
</junit>
</target>
However, this approach does not work for groovy tests as those are in *.groovy files and the JUnit Ant task, understandably, does not recognise them in the fileset.
The alternative approach is to use *.class files for the batchtest fileset like this:
<batchtest fork="yes" todir="${test.dir}/report">
<fileset dir="${test.dir}/${build.dir}">
<include name="**/*Test*.class" />
</fileset>
</batchtest>
This generates false negatives as closure class files are also included so a possible workaround is to exclude those files.
<batchtest fork="yes" todir="${test.dir}/report">
<fileset dir="${test.dir}/${build.dir}">
<include name="**/*Test*.class" />
<exclude name="**/*$*.class" />
</fileset>
</batchtest>
Is there a better way to identify test classes fo the junit ant task? Perhaps one based on reflection and the #Test attribute as manually listing all the test classes (which would work perfectly well) is not really a maintainable solution. Something like the SpecClassFileSelector from the Spock framework.
what about changing the include pattern to *Test rather than *Test*
as #jon-skeet suggested here.
This way it will not match the anonymous closure classes.
you'll have to rename your existing classes and ask the developers to follow this pattern.
Take a look at:
http://www.ibm.com/developerworks/java/library/j-pg11094/
There's a groovyc ant taskdef for compiling the groovy test cases and running them. The example there is Maven, but it shouldn't be too hard to adapt it to do what you want.
Can't you just write something like this?
<fileset dir="${test.dir}/unit" includes="**/*.java,**/*.groovy"/>
Related
I am working on a legacy project which needs to be upgraded to use Java8. During the upgrade we are facing issues with ANTL3.3 as it not compatible with Java8.
Now because of certain dependencies we cannot upgrade ANTLR version and ANTLR is used to generate Java files from Grammar(.g) files.
Now, in the ANT - build.xml. I want to divide it in 2 parts.
In which ANTLR target is run wherein the Grammar files being converted to Java files using. During this part I want to use Java1.7.
ANTLR - Garmmar ===Java1.7===> output generated Java files
Once Java files generated with 1.7 it should be compiled with existing Java files using Java8 and then final package should be prepared.
Generated Java files + existing java source code ===Java8===> Compile classes
Presumable you use the java Ant task to generate lexer- and parser classes from your .g grammar file, then you could use the jvm attribute to point to your 1.7 Java binary:
<java
jvm="/path/to/java-1.7/bin/java"
classname="org.antlr.Tool"
fork="true"
failonerror="true"
maxmemory="1024m">
<arg value="T.g" />
<classpath refid="classpath" />
</java>
where <classpath ... points to your ANTLR 3.3 JAR (and other classes you need might need in the classpath):
<?xml version="1.0" encoding="UTF-8"?>
<project>
<path id="classpath">
...
<fileset dir="lib">
<include name="*.jar" />
</fileset>
</path>
...
</project>
I am using the method proposed in this answer to compile Clojure *.clj files to *.class (and subsequently jar them), using more or less the structure of the compile-clojure target from the build.xml file that's found at the root of the Clojure distribution (e.g. in clojure-1.5.1.zip). In my case:
<java classname="clojure.lang.Compile"
failonerror="true"
fork="true">
<classpath refid="compile.classpath"/>
<sysproperty key="clojure.compile.path" value="${cljbuild.dir}"/>
<arg value="${project.MainClass.name}"/>
</java>
The problem with this approach is that it keeps compiling the *.clj files even though they haven't changed. Any ways around this?
For building Clojure projects where for various reasons I could not use Leiningen I have been much happier using the Zi plugin and letting maven decide what needs to be re-compiled.
I ended up using ant-contrib's OutOfDate task (e.g. as also described in this answer for the more general case of invoking Ant's exec task).
<contrib:outofdate>
<deletetargets all="true"/>
<sourcefiles>
<path refid="compile.dependency.artifacts"/>
</sourcefiles>
<targetfiles>
<fileset dir="${cljbuild.dir}">
<include name="**/*.class"/>
</fileset>
</targetfiles>
<sequential>
<java classname="clojure.lang.Compile"
failonerror="true"
fork="true">
<classpath refid="compile.classpath"/>
<sysproperty key="clojure.compile.path" value="${cljbuild.dir}"/>
<arg value="${project.MainClass.name}"/>
</java>
</sequential>
</contrib:outofdate>
I have Ant build file which is used in Docbook. Now I am going to convert that Ant build file to a Makefile which uses Xsltproc processor. I am not particularly familiar with either Makefile or Ant. So please help me to convert it. Are there any resources which I should follow?
Here I want to,
1. copy folder structure and its content into another folder
2. configure java system properties
3. configure classpath
In ant script, it has code like this,
<copy todir="${output-dir}">
<fileset dir="${ant.file.dir}/template">
<include name="**/*"/>
</fileset>
</copy>
<java classname="com.nexwave.nquindexer.IndexerMain" fork="true">
<sysproperty key="htmlDir" value="${output-dir}/content"/>
<sysproperty key="htmlExtension" value="${html.extension}"/>
<classpath>
<path refid="classpath"/>
<pathelement location="${xercesImpl.jar}"/>
<pathelement location="/usr/share/xml-commons/lib/xml-apis.jar"/>
</classpath>
</java>
I want to convert above 2 codes in make.
Thank you..!!
Make and ANT are very different technologies. Your requirement would difficult to fufil for all but the simplest use cases.
Here are some of the technical challenges:
ANT is not Make. On the surface it looks similar, but underneath works quite differently.
Surprisingly make is not very cross platform. Different flavours have subtle differences that could break an ANT to Makefile convertor.
ANT is designed to support Java programs, this means it has a rich syntax for managing nasty things like Java classpaths. Again difficult to translate.
Update
The following ANT java task
<java classname="com.nexwave.nquindexer.IndexerMain" fork="true">
<sysproperty key="htmlDir" value="${output-dir}/content"/>
<sysproperty key="htmlExtension" value="${html.extension}"/>
<classpath>
<path refid="classpath"/>
<pathelement location="${xercesImpl.jar}"/>
<pathelement location="/usr/share/xml-commons/lib/xml-apis.jar"/>
</classpath>
</java>
can be translated into the following unix java command-line.
java \
-DhtmlDir=$PUT_OUTPUT_DIR_HERE \
-DhtmlExtension=$PUT_EXT_HERE \
-cp $CLASSPATH:$PATH_TO_XERCES_JAR:/usr/share/xml-commons/lib/xml-apis.jar \
com.nexwave.nquindexer.IndexerMain
I'm trying to set up an ANT build script which compile code, compile tests, run unittests and then build. These are all done through separate targets with dependencies i.e.
<target name="compile">
<javac>...
</target>
<target name="compile-tests" depends="compile">
<javac>...
</target>
<target name="unittest" depends="compile-tests">
<junit...
<test ...
<fail if="tests.failed" ..
</target>
<target name="build" depends="compile, unittest">
</target>
Each 'test' inside the 'junit' task focuses on one part of the application, (typically package by package) and points to a Junit TestSuite. This set up allows for all tests to be run when a build is called but this isn't ideal for day-to-day development.
I would like to be able to do 2 things:
Run all the tests in a build (like the setup shown above)
Run tests individually from ant
My solution for (2) was to use multiple antcall tasks which isn't really best practice. During these calls different properties were set to run all the tests as they each required a different property:
<!-- test package p2 with ant unittest -Dtest.p2=true -->
<target name="unittest" depends="compile-tests">
<junit...
<test if="test.p1" ...
<test if="test.p2"
<fail if="tests.failed" ..
</target>
<target name="unittestall">
<property name="test.p1" value="true"/>
...
</target>
<target name="build" depends="compile, unittest">
<antcall target="unittestall" />
<antcall target="clean" />
<antcall target="compile" />
</target>
This gave the granularity I required but meant alot of work was duplicated and ant's dependency features weren't being used to their full.
So my question is:
How can I best set up ANT and Junit so that all tests can be run as part of a build AND so that individual tests can be run?
Thankyou :)
from Joshua England
p.s. ANT 1.8 and Junit 4.10 :)
Something like this?
<target name="unittest-p1"></target>
<target name="unittest-p2"></target>
<target name="unittest-p3"></target>
<target name="unittest" depends="unittest-p1, unittest-p2, unittest-p3/>
You could then run all the tests by passing the unittest target:
ant unittest
(or any target which depends on unittest)
And you could run any individual test of set of tests by invoking the appropriate target, e.g.
ant unittest-p1
If you would end up with a lot of duplication in multiple junit targets, you could tidy that up by putting all the common stuff into a macrodef.
Here is the ant statement -
<java jar="${lib.dir}/selenium-server-standalone-2.8.0.jar" fork="true" spawn="true" />
And I want to do -
<java jar="${lib.dir}/selenium-server-*.jar" fork="true" spawn="true" />
Hence I am not affected with version of jar I am using.
The Ant java task doesn't support regular expressions there. But you can use a fileset to 'find' the jar:
<fileset dir="${lib.dir}" id="selenium.jar" includes="selenium-server-*.jar" />
Then you can refer to the file using the ant.refid: prefix:
<java jar="${ant.refid:selenium.jar}" fork="true" spawn="true" />
If your library directory contains multiple versions of the jar this won't work: you need to decide which one to chose.
You could look into using a resource collection like first to pick just one, but I'm not sure that would necessarily give you the right one.