Ant JUnit task doesn't work in TeamCity - ant

There is part of ant script with junit task:
...
<target name="test">
<mkdir dir="path_to_report_dir">
<junit fork="true" printsummary="true" showoutput="true" maxmemory="1024M">
<classpath ... />
<batchtest todir="path_to_report_dir">
<formatter type="xml" />
<fileset ... />
</batchtest>
</junit>
</target>
...
This script works from Eclipse and from command line. But it doesn't work in TeamCity. The last informative message in TeamCity is:
[mkdir] Created dir: path_to_report_dir
Process exit code: 0
It looks like junit task doesn't work and also it stops performting aff all script. Where is trouble in?

The cause was in <fileset> file list. The TeamCity version of Ant doesn't work with strings like "/test/" (this mean select all files recursively); it only works with strings like "**/test/*.class". The local version of Ant supports both variants.
Thanks.

Don't know if this helps.... but here's my standard test target:
<target name="test" depends="compile-tests">
<junit printsummary="yes" haltonfailure="yes">
<classpath>
<path refid="test.path"/>
<pathelement path="${classes.dir}"/>
<pathelement path="${test.classes.dir}"/>
</classpath>
<formatter type="xml"/>
<batchtest fork="yes" todir="${test.reports.dir}">
<fileset dir="${test.src.dir}">
<include name="**/*Test*.java"/>
<exclude name="**/AllTests.java"/>
</fileset>
</batchtest>
</junit>
</target>
Build output:
test:
[junit] Running org.demo.AppTest
[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.056 sec
Notes
Using Junit 4.10.

Related

Failed junit test not catched by teamcity when using jacoco

I was trying to integrate code coverage on my project by using jacoco, ant and teamcity. However, I realized that when jacoco task is around the junit task, teamcity does not catch the failing tests and everything is a success even with test failed.
Here are my 2 test tasks to test with and without jacoco and see teamcity bahaviours.
1- with jacoco activated
<target name="-test">
<echo message="JaCoCo activated"/>
<!-- Import the JaCoCo Ant Task -->
<taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml"/>
<!-- Run your unit tests, adding the JaCoCo agent -->
<jacoco:coverage destfile="${bin}/jacoco.exec" xmlns:jacoco="antlib:org.jacoco.ant">
<junit fork="yes" printsummary="yes" haltonfailure="no" showoutput="false" failureProperty="test.failed" errorProperty="test.failed">
<classpath>
<path location="${lib}/${projectName}.jar"/>
<path refid="project.classpath"/>
</classpath>
<formatter type="xml"/>
<batchtest todir="${reportingHome}">
<fileset dir="${test}">
<include name="**/*Test.java"/>
</fileset>
</batchtest>
</junit>
</jacoco:coverage>
<copy todir="${completeReportDir}" overwrite="true">
<fileset dir="${reportingHome}">
<include name="*.xml"/>
</fileset>
</copy>
</target>
2- without jacoco
<target name="-test">
<echo message="JaCoCo activated"/>
<!-- Import the JaCoCo Ant Task -->
<taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml"/>
<!-- Run your unit tests, adding the JaCoCo agent -->
<!--<jacoco:coverage destfile="${bin}/jacoco.exec" xmlns:jacoco="antlib:org.jacoco.ant">-->
<junit fork="yes" printsummary="yes" haltonfailure="no" showoutput="false" failureProperty="test.failed" errorProperty="test.failed">
<classpath>
<path location="${lib}/${projectName}.jar"/>
<path refid="project.classpath"/>
</classpath>
<formatter type="xml"/>
<batchtest todir="${reportingHome}">
<fileset dir="${test}">
<include name="**/*Test.java"/>
</fileset>
</batchtest>
</junit>
<!--</jacoco:coverage>-->
<copy todir="${completeReportDir}" overwrite="true">
<fileset dir="${reportingHome}">
<include name="*.xml"/>
</fileset>
</copy>
</target>
Only jacoco task has been commented between the 2 releases of test.
Teamcity output
[CommonBuildTasks.-test] echo
[08:26:21]: [echo] JaCoCo activated
[08:26:21]: [CommonBuildTasks.-test] jacoco:coverage (4s)
[08:26:21]: [jacoco:coverage] Enhancing junit with coverage.
[08:26:22]: [jacoco:coverage] Running ca.thalesgroup.socialnetworkanalysisorchestrator.impl.client.SocialNetworkAnalysisOrchestratorServiceProviderTest
[08:26:25]: [jacoco:coverage] Tests run: 2, Failures: 1, Errors: 0, Time elapsed: 3.511 sec
[08:26:26]: [jacoco:coverage] Test ca.thalesgroup.socialnetworkanalysisorchestrator.impl.client.SocialNetworkAnalysisOrchestratorServiceProviderTest FAILED
[08:26:26]: [CommonBuildTasks.-test] copy
[08:26:26]: [copy] Copying 1 file to C:\TeamCity\buildAgent\work\cc10e09e43249f57\reports
As you can see, a test failed but teamcity has reported a successfull build.
Any idea why I got this behaviour?
Thanks
The answer is hidden in your call to the JUnit-Task:
<junit haltonfailure="no">...</junit>
With this configuration, the JUnit task does not fail the build on failing tests. This should lead to the desired behaviour:
<junit haltonfailure="yes">...</junit>
See the Ant documentation for the configuration of the JUnit task.
I solved this issue by using agent task instead of the coverage task. So, instead of
<jacoco:coverage destfile="${bin}/jacoco.exec" xmlns:jacoco="antlib:org.jacoco.ant">
Use:
<jacoco:agent property="agentvmparam" destfile="${bin}/jacoco.exec"/>
<junit fork="yes"...
<jvmarg value="${agentvmparam}"/>
</junit>
Agent task uses the same properties as the coverage task. Then you can start your junit task without wrapping it in coverage task. That way teamcity is able to intercept junit task output.

How to run dbunit task in ant?

It doesn't work in ant,
I'd like to run some classes that extend DatabaseTestCase
<path id="libs.dir">
<fileset dir="lib" includes="**/*.jar" />
</path>
<taskdef name="dbunit"
classname="org.dbunit.ant.DbUnitTask"/>
<!-- run all tests in the source tree -->
<junit printsummary="yes" haltonfailure="yes">
<formatter type="xml"/>
<batchtest fork="yes" todir="${reports.tests}">
<fileset dir="${src.tests}">
<include name="**/*Test*.java"/>
</fileset>
</batchtest>
</junit>
It says the following:
Buildfile: D:\kariakin\jdbc_task\build.xml
BUILD FAILED
D:\kariakin\jdbc_task\build.xml:15: taskdef class org.dbunit.ant.DbUnitTask cannot be found
using the classloader AntClassLoader[]
I think the problem is your taskdef, it's missing the path containing the dbunit jar:
<taskdef name="dbunit" classname="org.dbunit.ant.DbUnitTask" classpathref="libs.dir"/>

Empty Junit reports from ant

I am trying to use ant to run junit tests and generate reports.
I am able to successfully run the tests but the report files are empty.
What am I doing wrong ?
This is my build.xml :
<project name="JunitTest" default="test" basedir=".">
<property name="testdir" location="." />
<property name="srcdir" location="." />
<property name="full-compile" value="true" />
<property name="test.reports" value="./reports" />
<path id="classpath.base"/>
<path id="classpath.test">
<pathelement location="${testdir}" />
<pathelement location="${srcdir}" />
<path refid="classpath.base" />
</path>
<target name="clean" >
<delete verbose="${full-compile}">
<fileset dir="${testdir}" includes="**/*.class" />
</delete> `
</target>
<target name="compile" depends="clean">
<javac srcdir="${srcdir}" destdir="${testdir}" verbose="${full-compile}" >
<classpath refid="classpath.test"/>
</javac>
</target>
<target name="test" depends="compile">
<junit>
<classpath refid="classpath.test" />
<formatter type="brief" usefile="false" />
<test name="com.tests.nav1" />
</junit>
<junitreport todir="${test.reports}">
<fileset dir="${test.reports}">
<include name="TEST-*.xml" />
</fileset>
<report todir="${test.reports}" />
</junitreport>
</target>
</project>
and this is the output on the console :
[junit] Using CLASSPATH C:\eclipse\eclipse-java-helios-SR1-win32\eclipse\JunitWS\SeleniumTraining\src;C:\jars\junit.jar;C:\ant\lib\ant-launcher.jar;C:\ant\lib\ant.jar;C:\ant\lib\ant-junit.jar;C:\ant\lib\ant-junit4.jar
[junit] Testsuite: com.tests.nav1
[junit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 48.187 sec
[junit] ------------- Standard Output ---------------
[junit] testnav2
[junit] ------------- ---------------- ---------------
[junitreport] Using class org.apache.tools.ant.taskdefs.optional.TraXLiaison
[junitreport] Processing C:\eclipse\eclipse-java-helios-SR1-win32\eclipse\JunitWS\SeleniumTraining\src\reports\TESTS-TestSuites.xml to C:\Users\pmahajan\AppData\Local\Temp\null236099757
[junitreport] Loading stylesheet jar:file:/C:/ant/lib/ant-junit.jar!/org/apache/tools/ant/taskdefs/optional/junit/xsl/junit-frames.xsl
[junitreport] Transform time: 330ms
[junitreport] Deleting: C:\Users\pmahajan\AppData\Local\Temp\null236099757
BUILD SUCCESSFUL
Total time: 49 seconds
If you look at the ant snippet, there are a few issues:
You have set usefile=false, which means no output file is created
You have set formatter type=brief, which will print detailed information only for failed tests
You need to also specify the todir - the folder where the report has to go in the <test> tag - the default is current folder. This should match the folder you are using in <junitreport> task.
You can try with the following updated <junit> section...
<junit>
<classpath refid="classpath.test" />
<formatter type="xml"/>
<test name="com.tests.nav1" todir="${test.reports}"/>
</junit>
1 <target name="test" depends="compile">
2 <junit>
3 <classpath refid="classpath.test" />
4 <formatter type="brief" usefile="false" />
5 <test name="com.tests.nav1" />
6 </junit>
7 <junitreport todir="${test.reports}">
8 <fileset dir="${test.reports}">
9 <include name="TEST-*.xml" />
10 </fileset>
11 <report todir="${test.reports}" />
12 </junitreport>
13 </target>
The above segment of your coded needs following changes.
You have to specify the to directory option in the 5th line( for example todir = ${data.reports} )
In the 8th line the directory specified must me data.reports.
The 11th line must contain the option format with the value frames (format="frames").
The ant JUnit Task doc gives this example that might help you (as it apparently does exactly what you're trying to achieve):
<junit printsummary="yes" haltonfailure="yes">
<classpath>
<pathelement location="${build.tests}"/>
<pathelement path="${java.class.path}"/>
</classpath>
<formatter type="plain"/>
<test name="my.test.TestCase" haltonfailure="no" outfile="result">
<formatter type="xml"/>
</test>
<batchtest fork="yes" todir="${reports.tests}">
<fileset dir="${src.tests}">
<include name="**/*Test*.java"/>
<exclude name="**/AllTests.java"/>
</fileset>
</batchtest>
</junit>
Runs my.test.TestCase in the same VM, ignoring the given CLASSPATH; only a warning is printed if this test fails. In addition to the plain text test results, for this test a XML result will be output to result.xml. Then, for each matching file in the directory defined for ${src.tests} a test is run in a separate VM. If a test fails, the build process is aborted. Results are collected in files named TEST-name.txt and written to ${reports.tests}.
It is specified in the doc that printsummary can take values on and off, but they're using yes in the example which is on the same page, so I guess it's accepted too.
Please try formatter with "xml"
<formatter type="${junit.format}"/>
where junit.format is property with appropriate value.

Running jUnit tests via ANT, clarification needed

Suppose you have a test directory that contains packages each of which contains jUnit tests.
In this setup, using ANT, how would you "run all tests?"
Assuming my jUnit has
<target name="test" depends="compileTest">
<junit fork="yes" printsummary="yes" haltonfailure="no">
<classpath location="${bin}" />
<formatter type="plain" />
<test name="_com.??.project.alltests.MyTests" />
</junit>
</target>
Where, MyTests has
#RunWith(Suite.class)
#Suite.SuiteClasses( { _ThisTest.class, _ThatTest.class })
public class OCTTests {
}
and _ThisTest itself contains some tests ..
Is it possible for the purposes of ANT script to avoid this ans simply say "Run all Tests you find in this directory"
Have a look at the nested batchtest element of the junit task.
You will find the following example on the junit task documentation page:
<junit printsummary="yes" haltonfailure="yes">
<classpath>
<pathelement location="${build.tests}"/>
<pathelement path="${java.class.path}"/>
</classpath>
<formatter type="plain"/>
<test name="my.test.TestCase" haltonfailure="no" outfile="result">
<formatter type="xml"/>
</test>
<batchtest fork="yes" todir="${reports.tests}">
<fileset dir="${src.tests}">
<include name="**/*Test*.java"/>
<exclude name="**/AllTests.java"/>
</fileset>
</batchtest>
</junit>

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.

Resources