controlling which JUnit tests are run by Ant - ant

I have an ant task set up like so:
<target name="unit-test" description="unit tests" depends="compile-tests">
<mkdir dir="${build}/test"/>
<mkdir dir="${build}/test/raw"/>
<mkdir dir="${build}/test/reports"/>
<!-- set up scratch database for tests -->
<mkdir dir="${build.dbTest}" />
<junit printsummary="yes" haltonfailure="no" maxmemory="512m" >
<classpath>
<pathelement path="${java.class.path}"/>
<pathelement path="${build.classes}"/>
<pathelement path="${build.test-classes}"/>
<fileset dir="lib" includes="*.jar"/>
<fileset dir="lib-test" includes="*.jar"/>
</classpath>
<formatter type="xml"/>
<sysproperty key="derby.system.home" value="${build.dbTest}" />
<batchtest fork="yes" todir="${build}/test/raw">
<fileset dir="${src.test}">
<include name="**/*Test.java"/>
</fileset>
</batchtest>
</junit>
<junitreport todir="${build}/test">
<fileset dir="${build}/test/raw"/>
<report todir="${build}/test/reports"/>
</junitreport>
</target>
Which works pretty well for running all my tests, but running all my tests really slows down my TDD Fail-Pass-Refactor groove. My full test suite takes about six minutes to run, which is way too long for quick response changes during TDD, especially since most of the time I only care about results from one test. The work flow I'd like to have would be
create test for new feature/bug
run only the new test (or at most only the test class I just modified)
write some code
iterate 2-3 until the new tests are passing
run full set of tests to make sure nothing else broke
plug any broken test into the 2-3 cycle above and repeat full cycle
when all tests pass, declare victory.
TestNG seems to have capability for grouping tests, which seems ideal (I could have a "TDD" group for the tests I'm currently working with. Changing that when I start working on something is an acceptable level of manual configuration here), but I don't want to switch test frameworks unless I absolutely have to. Is there any way to do something similar, or another way to achieve my desired work flow, using JUnit?

I use in my scripts instead of
<include name="**/*Test.java"/>
the snippet
<include name="${test}"/>
and set the property test to **/*Test.java earlier in the script. Now I can start ant, setting the property to a different value:
ant test -Dtest=**/*AcceptanceTests.java

Related

Ant for script how to continue if any iteration fails

I writing an ant build file to check all translate files in a directory.
I want the ant for script to continue checking the rest files if an checking error in any file appear.
My ant task:
<taskdef name="validate" classname="ValidateTranslateFile">
<classpath>
<pathelement location="${ant-libs-dir}/TranslateFileUtilities.jar" />
<pathelement location="../web/WEB-INF/lib/commons-io-2.5.jar" />
<pathelement location="../web/WEB-INF/lib/commons-lang3-3.5.jar" />
</classpath>
</taskdef>
<for param="program">
<path>
<fileset dir="../web/WEB-INF" includes="*.txt" />
</path>
<sequential>
<validate targetFile="#{program}" checkLanguages="true" checkKeysOrder="true" />
</sequential>
</for>
</target>
the Result:
it checks the files till the first error appear, and then the BUILD FAILED.
Could any one help me with that?
The for task is not part of standard ANT. It is a 3rd party extension documented here:
http://ant-contrib.sourceforge.net/tasks/tasks/for.html
The documentation suggests using a "keepgoing" attribute to ignore errors, this might be the answer you're looking for.
If this is a custom ANT task you are writing, perhaps you should consider refactoring the code to operate on a fileset? This would enable you to call task as follows:
<validate checkLanguages="true" checkKeysOrder="true">
<fileset dir="../web/WEB-INF" includes="*.txt" />
</validate>
Simpler and more robust.

Cobertura - Code Coverage Instrumentation

I am trying some code-coverage analysis for first time and I was working on getting cobertura using ANT. My questions might be silly, but thought of asking here. I have the following in my ANT scripts. While reading over through cobertura the next step was instrumentation. What is code coverage instrumentation?
<target name="cobertura" depends="checkstyle">
<property name="cobertura.dir" location="C:\\Softwares- packages\\Corbetura\\cobertura-1.9.4.1" />
<path id ="cobertura.classpath">
<fileset dir="${cobertura.dir}">
<include name="cobertura.jar"/>
<include name="lib/**/*.jar"/>
</fileset>
</path>
<taskdef resource="tasks.properties" classpathref="cobertura.classpath"/>
</target>
cobertura modifies your class files so that it can compute the coverage. I typically 'instrument' a copy of the jar files that I use for executing tests and use a copy that hasn't been instrument as my build artifact.
Here is the build file I used when I first set up cobertura via ant:
The cobertura-instrument target instruments my code and writes the instrumented classes to a separate directory like you said.
The junit target compiles the test, then instruments the tests, then runs the tests, then produces the report. These steps are all done by declaring dependent targets to the junit one.
<path id="cobertura.classpath">
<fileset dir="${cobertura.dir}">
<include name="cobertura.jar" />
<include name="lib/**/*.jar" />
</fileset>
</path>
<taskdef classpathref="cobertura.classpath" resource="tasks.properties" />
<!-- Delete an existing coburtura datafile -->
<delete file="${cobertura.datafile}"/>
<antcall target="cobertura.clean"/>
<!-- Instrument the code with cobertura to test for coverage -->
<cobertura-instrument todir="${cobertura.instrumented.classes}" datafile="${cobertura.datafile}">
<fileset dir="${build.dir}/classes/">
<include name="**/*.class"/>
</fileset>
</cobertura-instrument>
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
<fileset dir="${tests.src.dir}">
<include name="**/*.java" />
</fileset>
I believe you're looking for the "cobertura-instrument" task. See here

Ant build target is failing after first junit task

I have an Ant build target that performs some testing using jUnit4
<target name="integrationtest" depends="init, buildtests, deploytests">
<junit haltonfailure="false">
<sysproperty key="driver" value="org.openqa.selenium.firefox.FirefoxDriver" />
<sysproperty key="screenshotDir" value="${screenshotsDir}" />
<classpath>
<pathelement location="${interfaceTestJar}"/>
</classpath>
<batchtest>
<fileset dir="${interfaceTestClasses}">
<include name="**/tests/Test*.class" />
</fileset>
</batchtest>
</junit>
<junit haltonfailure="false">
<sysproperty key="driver" value="org.openqa.selenium.ie.InternetExplorerDriver" />
<classpath>
<pathelement location="${interfaceTestJar}"/>
</classpath>
<batchtest>
<fileset dir="${interfaceTestClasses}">
<include name="**/tests/Test*.class" />
</fileset>
</batchtest>
</junit>
<echo message="##teamcity[publishArtifacts '${artifactsDir}']" />
</target>
First junit task is always started, but if there is any failed tests in it, the second one isn't starts (exepected to start in any case, even if first one has failed tests)
EDIT: Seems like there is another problem. Second jUnit is not started in any case (if first is succeed or failed). In my TeamCity build log i see the following lines
[integrationtest] junit
[20:06:14]: [junit] ru.company.tests.TestDateField
[20:06:30]: [junit] Process exited with code 255
TestDateField is my first test suite. After it there are some more suites and they all succeed (and the first one too).
Is there a chance your test does something like System.exit?
Did you try adding fork="true" to your junit task, so it will run in a separate JVM?
I think you should use <junit haltonfailure="no"> instead of <junit haltonfailure="false">
As per the docs, haltonfailure should be yes or no.

Simple ant build script that supports src/ and test/?

Currently I use an IDE for all my builds and unit tests. Now I have a need to use ant. I found a few simple ant build.xml scripts but they didn't support a separate Junit test/ dir. My projects are structured as follows:
src/
com/foo/
com/bar/
test/ -- Mirror of src/, with all *Test.java files.
com/foo/
com/bar/
lib/ -- All Java libs, including junit 4.
How can a construct a small ant script that builds my src/ and test/ Java classes then runs all my JUnit tests?
I define <path> elements for each target.
This is an excerpt from my build file, you'll have to adapt some paths and properties, but you can get the idea:
<path id="src.path">
<pathelement path="src/"/>
</path>
<path id="compile.path">
<path refid="src.path"/>
<fileset dir="lib/">
<include name="**/*.jar"/>
</fileset>
</path>
<path id="unit.test.path">
<path refid="compile.path"/>
<pathelement path="test/"/>
</path>
<target name="compile">
<javac destdir="bin">
<src path="src"/>
<classpath refid="compile.path"/>
</javac>
</target>
<target name="compileUnitTests" depends="compile">
<javac srcdir="test/" destdir="bin">
<classpath refid="unit.test.path"/>
</javac>
</target>
<target name="runUnitTests" depends="compileUnitTests">
<junit printsummary="yes" haltonfailure="no">
<jvmarg value="-Dfile.encoding=UTF-8"/>
<classpath refid="unit.test.path"/>
<formatter type="xml"/>
<batchtest fork="yes" todir="${this.report}">
<fileset dir="test">
<include name="${test.pattern}"/>
<exclude name="**/AllTests.class"/>
<exclude name="**/*$*.class"/>
</fileset>
</batchtest>
</junit>
</target>
And if you need to refine this to your needs, as cotton.m says, go read the ant task docs. Using ant with your specific directory structure does require some knowledge of the tool, don't expect you'll easily find ready-made examples that just work with your exact requirements.
I don't understand the question. Are you asking how to set the default target? Select which target to run when executing or do you just not know how to write build.xml files? It's not that hard really. See http://ant.apache.org/manual/tutorial-HelloWorldWithAnt.html and http://ant.apache.org/manual/

Running "pure" JUnit 4 tests using ant

We have migrated to both JUnit 4 and ant 1.7
The tests runs fine in eclipse, but the annotations are ignored when running the tests using ant.
According to the Ant junit task documentation:
It also works with JUnit 4.0, including "pure" JUnit 4 tests using only annotations and no JUnit4TestAdapter.
But the documentation doesn't elaborate on how it should be configured.
Is there any special setting required for the junit task? Am I missing something?
We have both Tests that extends TestCase (i.e. 3.8 style) and "pure" Junit 4 tests, could that be the problem?
I am using pure JUnit4 tests with Ant.
Here is the interesting part of my build file:
<junit printsummary="yes" haltonfailure="yes">
<formatter type="xml"/>
<classpath refid="path.test"/>
<batchtest fork="yes" todir="${dir.report.unittests.xml}">
<fileset dir="src">
<include name="**/*Test*.java"/>
</fileset>
</batchtest>
</junit>
Make sure you have the latest version of the junit.jar file in the lib directory of Ant. As far as I know the required version is delivered with ant 1.7 or higher versions...
Ant ships with a version of JUnit 3 by default. JUnit 3 has no support for test annotations.
To use the JUnit 4 annotations from the junit task make sure that you provide the location of a JUnit 4 jar in a nested classpath element of the junit task (see this entry in the ant FAQ).
<junit showoutput="yes" fork="true">
<classpath>
<!-- The location of the JUnit version that you want to use -->
<pathelement location="lib/junit-4.9b1.jar"/>
</classpath>
<formatter type="plain" usefile="false" />
<batchtest>
<fileset dir="${tests.dir}"/>
</batchtest>
</junit>
This is a preferable solution to overwriting the ant-junit.jar in ANT_HOME/lib as it means you can keep your JUnit jar in source control alongside your code making upgrades to later versions straightforward.
Note that whilst I haven't specified any include pattern in my fileset above this does mean that the junit task will attempt to run JUnit against all the classes in that directory structure which might result in a number of classes being included that don't contain any tests depending on how you have structured your source files.
You can finally only find and execute tests with the skipNonTests parameter added in ant 1.9.3+!
This is the code snippet from the accepted answer above (except for the new skipNonTests parameter and getting rid of the "Test" in the filename requirement):
<junit printsummary="yes" haltonfailure="yes">
<formatter type="xml"/>
<classpath refid="path.test"/>
<batchtest skipNonTests="true" fork="yes" todir="${dir.report.unittests.xml}">
<fileset dir="src">
<include name="**/*.java"/>
</fileset>
</batchtest>
</junit>
This happened to me and it was because I was both using annotations and extending TestCase.
public class TestXXX extends TestCase {
#Test
public void testSimpleValidCase() {
// this was running
}
#Test
public void simpleValidCase() {
// this wasn't running
}
}
When you extend TestCase you are assuming JUnit3 style so JUnit4 annotations are ignored.
The solution is to stop extending TestCase.
Verify your classpath definition...
this solved my problem.
<path id="classpath" description="Classpath do Projeto">
<fileset dir="${LIB}">
<include name="**/*.jar" />
<exclude name="**/.SVN/*.*"/>
</fileset>
</path>
This is the relevant part of my generic ant script... not sure if that'll help you or not..
<junit fork="true"
forkmode="once"
haltonfailure="false"
haltonerror="false"
failureproperty="tests.failures"
errorproperty="tests.errors"
includeantruntime="true"
showoutput="true"
printsummary="true">
<classpath>
<path refid="path-id.test.classpath.run"/>
</classpath>
<formatter type="xml"/>
<batchtest fork="yes"
todir="${dir.build.testresults}">
<fileset dir="${dir.src.tests}">
<include name="**/*Test.java"/>
</fileset>
</batchtest>
</junit>
Apply this annotation to the other classes org.junit.Ignore
I also tried to do tests with JUnit 4.0 without JUnit4TestAdapter, i.e. without method
public static junit.framework.Test suite() {
return new JUnit4TestAdapter(SomeTestClass.class);
}
I use ant 1.9.4.
Running ant test verbose (ant -v ) shows
[junit] Running multiple tests in the same VM
[junit] Implicitly adding /usr/share/java/junit.jar:/usr/sharejava/ant-launcher.jar:/usr/share/java/ant.jar:/usr/share/java/ant/ant-junit.jar to CLASSPATH
Aha, but still there is some ant-junit-task.
Downloading this shows in addition
/usr/share/java/ant/ant-junit4.jar which is not added implicitly.
I just added it explicitly:
<junit printsummary="yes"
fork="yes"
forkmode="once"
maxmemory="1023m"
showoutput="no">
...
<classpath>
<pathelement path="...:${junitJar}:${hamcrestJar}:/usr/share/java/ant/ant-junit4.jar" />
</classpath>
...
</junit>
and it worked. Without: no.
I am aware that this solution is not beautiful at all...
What I ended up doing was adding an Ant to one of my definitions that is used by the task>. Et voila.

Resources