taking output on console when running junit through ant script - java

I am using ant script and running a junit, the problem I am facing is that I am unable to get the output on console, rather I get the output in a log file.
how can I achieve that..
I am using the following script.
<target name="validate_mapping" description="Testing the Hibernate ">
<path id="validator.classpath">
<fileset dir="${basedir}\lib">
<include name="Junit-Temp-Test.jar" />
</fileset>
</path>
<junit printsummary="yes">
<formatter type="plain"/>
<test name="com.ofss.fc.junit.test.SampleTest" />
<classpath>
<path refid="validator.classpath" />
<path refid="lib.ext.classpath" />
</classpath>
</junit>
</target>

I think you need to specify "usefile" attribute <formatter usefile="false" type="plain"/>

Related

JUnit Ant ClassNotFoundException

I am getting a java.lang.ClassNotFoundException when I run my target TranslatorWorkflow that is supposed to execute a JUnit test. I am running a build.xml file with the targets: build TranslatorWorkflow. It compiles but fails on the JUnit test immediately.
My TranslatorWorkflow.class file is in {basedir}/bin/testScripts/. My classpath and target are:
classpath:
<path id="classpath">
<fileset dir="${basedir}/lib/binaries" includes="*.jar" />
<pathelement location="${basedir}/bin/testScripts/" />
</path>
TranslatorWorkflow target in my build.xml file:
<target name="TranslatorWorkflow">
<mkdir dir="${junit.output.dir}" />
<junit fork="yes" printsummary="withOutAndErr">
<formatter type="xml" />
<test name="testScripts.TranslatorWorkflow" todir="${junit.output.dir}" />
<classpath refid="classpath" />
</junit>
</target>
I attempted to emulate this answer to a similar question by adding the pathelement line shown in my classpath section above, but received the same exception. I've looked at this question as well as it seems like the same deal. I'd imagine there is something super obvious that I'm missing but alas I don't seem to be getting it.
The classpath should reference ${basedir}/bin not ${basedir}/bin/testScripts (i.e. it should reference the root of classes directory, not the package in which the class exists):
<path id="classpath">
<fileset dir="${basedir}/lib/binaries" includes="*.jar" />
<pathelement location="${basedir}/bin/" />
</path>
Dumpcats, try this...
<path id="base.path">
<pathelement path="${sun.boot.class.path}"/>
<pathelement path="${sun.boot.library.path}"/>
<fileset dir="${basedir}">
<include name="**.jar"/>
</fileset>
</path>
And then in the target element ...
<target name="runTest">
<mkdir dir="test_reports"/>
<junit
fork="true"
forkmode="once"
maxmemory="256m">
<formatter type="plain" usefile="false"/>
<formatter type="xml"/>
<classpath refid="base.path"/>
<batchtest
haltonerror="true" haltonfailure="true"
todir="test_reports">
<fileset dir="${test.build}">
<include name="**/*Test*.class"/>
<include name="**/Test*.class"/>
<include name="**/*Test.classp"/>
<!-- Exclusions -->
<exclude name="**/util/*.class"/>
</fileset>
</batchtest>
</junit>
</target>
At least is that is how i manage classpath reference and everything works like a charm.

ClassNotFoundException - when running ant-junit

I'm trying to create a Proof of concept for the actual application, The task is to run ant-junit tests without adding stuff to the global environment. I've achieved it so far in ant, but, I'm stuck with the following exception. ClassTest.java is the java class that has sample unit testcase. (Junit 3.0 style). I'm not sure why ant-junit does not find the class inspite of mentioning the paths in the batchrun task.
project structure
I get the following exception when running ant-junit task.
Testsuite: ClassTest
Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
Caused an ERROR
ClassTest
java.lang.ClassNotFoundException: ClassTest
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:249)
at org.eclipse.ant.internal.launching.remote.EclipseSingleCheckExecutor.executeTargets(EclipseSingleCheckExecutor.java:30)
at org.eclipse.ant.internal.launching.remote.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
at org.eclipse.ant.internal.launching.remote.InternalAntRunner.run(InternalAntRunner.java:424)
at org.eclipse.ant.internal.launching.remote.InternalAntRunner.main(InternalAntRunner.java:138)
My ant build.xml file is
<project name="Java project build" default="build">
<property name="project.local.directory" value="C:\Users\usrpao\workspace\Ant" />
<property name="src.path" value="${project.local.directory}/src" />
<property name="lib.path" value="${project.local.directory}/lib" />
<property name="dest.path" value="${project.local.directory}/target" />
<property name="junit.output.dir" value="${project.local.directory}/junit" />
<path id="classpath.test">
<fileset dir="lib">
<include name="**/*.jar" />
</fileset>
</path>
<!--<taskdef name="junit" classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask">
<classpath refid="classpath.test" />
</taskdef> -->
<path id="MyProject.classpath">
<pathelement location="lib/ant-junit.jar" />
<pathelement location="lib/junit.jar" />
<pathelement location="bin/*.*"/>
</path>
<path id="lib.classpath">
<pathelement location="lib/ant-junit.jar" />
<pathelement location="lib/junit.jar" />
</path>
<target name="build" depends="clean">
<javac srcdir="${src.path}" destdir="${dest.path}" classpathref="lib.classpath">
</javac>
<antcall target="test">
</antcall>
</target>
<target name="clean">
</target>
<target name="test">
<pathconvert property="testoutput" refid="classpath.test" />
<echo>Path = ${testoutput}</echo>
<mkdir dir="${junit.output.dir}" />
<junit haltonerror="false" showoutput="true">
<classpath refid="MyProject.classpath">
</classpath>
<batchtest todir="${junit.output.dir}">
<formatter type="plain" />
<fileset dir="${src.path}/com/ant/test">
<include name="**/*Test*.java" />
</fileset>
</batchtest>
</junit>
</target>
Your classpath is referencing the bin directory while the classes are actually under the target directory. You should change the MyProject.classpath reference to include ${project.local.directory}/target:
<path id="MyProject.classpath">
<pathelement location="lib/ant-junit.jar" />
<pathelement location="lib/junit.jar" />
<dirset dir="${project.local.directory}">
<include name="target"/>
</dirset>
</path>
In addition, you should change the fileset element inside the junit task by removing the folders corresponding to the package name of the test class, otherwise you will still get a ClassNotFoundException:
<junit haltonerror="false" showoutput="true">
<classpath refid="MyProject.classpath">
</classpath>
<batchtest todir="${junit.output.dir}">
<formatter type="plain" />
<fileset dir="${src.path}"> <!-- remove com/ant/test corresponding to package name -->
<include name="**/*Test*.java" />
</fileset>
</batchtest>
</junit>
From your folder structure it is evident that the class ClassTest.class is in target folder. so in class-path you should include following:
<pathelement path="target"/>
Hope this helps.

Filtering junit test classes from Emma Code Coverage Report

I have a project where I have the emma code coverage script (using ant) building and generating the tests correctly.
I have two packages
com.myproject.abc
test.com.myproject.abc
All of the junit tests are in the test.com.mywebsite.abc package. My goal is to NOT have the test.com.myproject.abc package included in the report (coverage.xml). I've read the emma documentation about coverage filters and looked at several other examples, but cannot get it to work without including the junit tests in the instrumentation.
If I include the filter in the instrumentation target ... it does not instrument the junit classes, which are used for the junit test. The result is a classNotFoundException.
Here is my code.
<target name="emma-instrument" depends="clean" description="instruments the code">
<emma enabled="true">
<instr instrpath="${classes}" destdir="${emma.instr.dir}"
metadatafile="${emma.coverage.dir}/coverage.emma" merge="true" >
<filter excludes="test.com.myproject.abc"/>
</instr>
</emma>
</target>
When the instrumentation happens, it moves all of the instrumented classes to emma/instrumentation - which IS included in the classpath.
<target name="test" depends="test_preconditions" description="run junit tests">
<junit fork="yes" printsummary="yes" haltonfailure="yes">
<classpath refid="test.classpath" />
<formatter type="plain" usefile="false" />
<batchtest>
<fileset dir="${classes}">
<include name="**/*Test*"/>
</fileset>
</batchtest>
<jvmarg value="-Demma.coverage.out.file=${emma.coverage.dir}/coverage.emma" />
<jvmarg value="-Demma.coverage.out.merge=true" />
<jvmarg value="-XX:-UseSplitVerifier"/>
</junit>
</target>
So just to repeat - is it possible to exclude the JUNIT tests from the Emma Coverage report? What do I need to change? Thanks in advance.
I am using emma 2.1 (code coverage), java and ant.
You could use the JaCoCo library like so:
<target name="test" depends="test_preconditions" description="run junit tests">
<mkdir dir="${test.data.dir}" />
<!-- Run all tests -->
<jacoco:coverage destfile="${test.data.dir}/jacoco.exec">
<junit fork="yes" printsummary="yes" haltonfailure="yes">
<classpath refid="test.classpath" />
<formatter type="plain" usefile="false" />
<batchtest>
<fileset dir="${classes}">
<include name="**/*Test*"/>
</fileset>
</batchtest>
</junit>
</jacoco:coverage>
<!-- Generate Code Coverage report
See: http://www.eclemma.org/jacoco/trunk/doc/ant.html -->
<jacoco:report>
<executiondata>
<file file="${test.data.dir}/jacoco.exec" />
</executiondata>
<structure name="AntTestReporting">
<classfiles>
<fileset dir="${build.dir}">
<include name="**/*.class" />
<!-- Exclude classes necessary for testing only from the code coverage report-->
<exclude name="**/*Test*.class" />
<!-- Exclude inner classes -->
<exclude name="**/*$*.class" />
</fileset>
</classfiles>
</structure>
<html destdir="${coverage.reports.dir}" />
</jacoco:report>
</target>
You can find more info here.

Is it possible for Ant to lists failed tests at the end of a build?

The following snippet, from another thread, works to print a message and fail after all unit tests have been run :
<fail if="junit.failed" message="Oh no ! There were some failed unit tests :( "/>
However --- I don't see a how can I also record and print the NAMES of the failed tests in junit/ant, after they have all run. Any thoughts on this ?
I believe others would find such function extremely important, so I'm assuming a simple solution exists : its quite tedious to look through hundreds of failed tests for the offenders.
Yes it is. Try using the junitreport task.
e.g.
Try this attribute on your junit task:
printsummary="yes" on junit task
Change your formatter to:
<formatter type="xml" />
and then create the reports with a target that calls this:
<junitreport>
<fileset dir="${testReport.dir}/tmp">
<include name="*.xml" />
</fileset>
<report format="frames" styledir="${testReportXslt.dir}" todir="${finalReport.dir}/html" />
</junitreport>
For output :
<concat>
<fileset dir="${finalReport.dir}/html" includes="*.html"/>
<filterchain>
<linecontainsregexp>
<regexp pattern='some pattern' />
</linecontainsregexp>
</filterchain>
</concat>
I'm sure that many of you have no desire to build a custom formatter or whatever. I don't either. I discovered that, with the following configuration, test successes are printed to stdout while failures are printed to stderr:
<target name="test"
depends="compile-tests"
description="runs the unit tests">
<junit failureproperty="hasFailingTests"
printsummary="on"
showoutput="true">
<formatter type="plain" usefile="false" />
<batchtest>
<fileset dir="${test.dir}">
<include name="**/*Test.java" />
<exclude name="**/Abstract*Test.java" />
</fileset>
</batchtest>
<classpath refid="tests.classpath"></classpath>
</junit>
<fail if="hasFailingTests" />
</target>
That means that running the following command:
ant test > /dev/null
will only show stderr with the test failures to the console, making it much easier to see what actually failed.
I think I finally have a complete answer to this question : Thanks to FailedDev's insights .
First, Make sure you ${reports.dir} variable, specifying the directory for the reports :
<property name="reports.dir" value="reports" />
Then , when we begin coding the test instructions junit :
<target name="test" depends="compile">
Then, make necessary directories for the reports :
<mkdir dir="${reports.dir}" />
<mkdir dir="${reports.dir}/tmp" />
<mkdir dir="${reports.dir}/style" />
<mkdir dir="${reports.dir}/final" />
Since we have a report scanner, we can set haltonfailure to no, and fail after (scroll down).
<junit printsummary="yes" failureproperty="junit.failed" haltonfailure="no" fork="yes" forkmode="once">
<jvmarg value="-Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl" />
<classpath refid="common.classpath" />
<classpath>
<pathelement location="${build.dir}" />
<pathelement location="${src.dir}" />
</classpath>
<formatter type="xml" />
<batchtest todir="${reports.dir}">
<fileset dir="${test.dir}">
<include name="**/Test*.java" />
<exclude name="**/AllTests.java" />
<exclude name="**/*.properties" />
<exclude name="**/*.xml" />
</fileset>
</batchtest>
</junit>
Now, here is where the advice of other questions comes in : run the junit report.
<!-- Capture all failures, simple debugging statements. -->
<junitreport>
<fileset dir="${reports.dir}/tmp">
<include name="*.xml" />
</fileset>
<report todir="${reports.dir}/final" />
</junitreport>
And finally, we can grep the xml files, directly, for errors :
<!-- This could be its own task, i.e., a java class which directly processed junit test data. -->
<echo message="Now checking xml test results for errors" />
<exec executable="grep" error="/dev/null">
<arg value="-r" />
<arg value="-m" />
<arg value="1" />
<arg value="-rl" />
<arg value="errors=\"[1-9]\"" />
<arg value="${reports.dir}" />
</exec>
Now, since we are'nt failing early (rather we are running the whole build, so we can see which tests failed , if any) we still have to notify the builder that we have failed... This is done via the fail-if syntax :
<fail if="junit.failed" message="FAILING - unit tests failed." />
<!-- Now, we check if there were failures, and output the results -->
</target>
Removing my comments, this code-block should work perfectly if you paste it into your build.

Run all unit tests with Ant builder

I have a directory with a bunch of JUnit tests in my project. So far I have used separate target for each unit test. For example:
<target name="MyTest">
<mkdir dir="${junit.output.dir}"/>
<junit fork="yes" printsummary="withOutAndErr">
<formatter type="xml"/>
<test name="tests.MyTest" todir="${junit.output.dir}"/>
<classpath refid="MyProject.classpath"/>
</junit>
</target>
This method requires me to change build file every time I add a Unit test.
I want to able able to to run all unit tests in the project with a single Ant builder target. Is it possible to do?
Yep it is, you need to look at the fileset tag, e.g:
<junit printsummary="yes" haltonfailure="yes">
<classpath>
<pathelement location="${build.tests}"/>
<pathelement path="${MyProject.classpath}"/>
</classpath>
<formatter type="xml"/>
<batchtest fork="yes" todir="${reports.tests}">
<fileset dir="${src.tests}">
<include name="**/*Test*.java"/>
<exclude name="**/AllTests.java"/>
</fileset>
</batchtest>
</junit>
The important part is the use of fileset and a glob/wildcard pattern to match the names of the tests. Full docs on the junit task with examples here:
http://ant.apache.org/manual/Tasks/junit.html
Yep! We do it using an ant command batchtest. Looks like this:
<batchtest todir="${junit.report.dir}">
<fileset dir="${basedir}\test\unit">
<include name="**/*Test.java" />
</fileset>
</batchtest>
Google it, it should sort you out

Categories