JUnit & Ant : How to show detailed error message on the screen? - java

I put up an Ant project which includes a unit test using JUnit.
The test target is as:
<target name="test">
<mkdir dir="target/test/reports"/>
<junit printsummary="yes" haltonfailure="yes">
<classpath>
<pathelement location="${test.classes.dir}"/>
<pathelement location="${test.junit.jar}" />
<pathelement path="${classes.dir}"/>
<pathelement path="${java.class.path}"/>
</classpath>
<formatter type="plain"/>
<batchtest fork="yes" todir="${test.reports.dir}">
<fileset dir="${test.src.dir}">
<include name="**/*Test*.java"/>
</fileset>
</batchtest>
</junit>
</target>
When I run this test, it show on the screen only the summary of the test like:
Buildfile: F:\test\build.xml
test:
[junit] Running com.mycompany.myproject.myTest
[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.013 sec
[junit] Running com.mycompany.myproject.myTest1
[junit] Tests run: 3, Failures: 1, Errors: 0, Time elapsed: 0.018 sec
BUILD FAILED
F:\test\build.xml:30: Test com.mycompany.myproject.myTest1 failed
Total time: 1 second
Is there anyway I can tell JUnit or Ant to display the detailed result on the screen?
Also, if I want to write something in the Unit test to the screen, how can I do this? I tried to insert System.out.println() in the test but it does not display anything on the screen.
Many thanks.

Set the showOutput flag to true.
What are you trying to accomplish via the S.o.p in the middle of a test?

change printsummary value to withOutAndErr, that will cause JUnit to print System.out and System.err text

IMHO, you are solving the wrong problem.
The junit results are collected and sitting "${test.reports.dir}" to be 'seen' by you. Ant has task that could help you in getting an HTML report
Introduce a target to generate html from the collected data (they are XML files)
<junitreport todir="./reports">
<fileset dir="${test.reports.dir}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="./report/html"/>
</junitreport>

Also, if you want to print something to the screen, just use
<echo message="My message..." />

<batchtest fork="yes" todir="${junit.report.dir}">
<formatter type="xml" />
<fileset dir="${application.build.stage.java.class.dir}">
<include name="**/*Test.class" />
</fileset>
</batchtest>
You can use this in your build.xml to generate the reports as html files.

Related

Ant and JUnit: test not performed

With Ant, you need to run JUnit-test. To use this code:
<target name="tempTest">
<mkdir dir="<folder in which to create the class-file>" />
<javac destdir="<folder in which to create the class-file>"
srcdir="<folder in which the java-file with junit-test>"
debug="on"
memorymaximumsize="128m"
fork="true"
encoding="utf-8">
<classpath>
<fileset dir="<folder, which is located in junit.jar>" includes="junit.jar"/>
</classpath>
</javac>
<junit printsummary="on" haltonfailure="no">
<classpath>
<fileset dir="<folder, which is located in junit.jar>" includes="junit.jar"/>
<pathelement location="<folder in which to create the class-file (in this step, class-file has been created in this folder)>"/>
</classpath>
<formatter type="plain"/>
<batchtest todir="<folder in which the file will be created for output to a test error>">
<fileset dir="<folder in which the java-file with junit-test>"/>
</batchtest>
</junit>
</target>
Code class take the test:
package ForTests;
import org.junit.Test;
public class TempTest {
#Test
public void testTemp() {
System.err.print("ERROR FOR TESTS");
}
}
However, when you run the ant-script file displays the error:
Testsuite: TempTest
Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
Caused an ERROR
TempTest
java.lang.ClassNotFoundException: TempTest
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
at com.intellij.rt.ant.execution.AntMain2.main(AntMain2.java:30)
Tell me, please, how to solve the problem?
UPD:
Issue has been resolved.
In order to run junit-test line must
<batchtest todir="<folder in which the file will be created for output to a test error>">
<fileset dir="<folder in which the java-file with junit-test>"/>
</batchtest>
replaced
<batchtest todir="<folder in which the file will be created for output to a test error>">
<fileset dir="<folder in which to create the class-file (in this step, class-file has been created in this folder)>"/>
</batchtest>

No runtime coverage using emma, junit and ant

I have the following project structure:
src/com/dummy/abc.java
src_tests/come/dummy/abcTest.java
build.xml
I need to check the coverage of my code done by tests using emma.
From reading the emma + junit examples i came to a conclusion that to get a report i need to do the following:
compile 'src'
compile 'src_tests'
instrument compiled 'src_tests' => 'instrumented_src_tests'
run junit on 'instrumented_src_tests' with additional jvmarg
The problem is that the step 4 should return some kind of a file which then used with 'report' command should create a report. I'm getting
emma-report:
[report] processing input files ...
[report] 1 file(s) read and merged in 67 ms
[report] nothing to do: no runtime coverage data found in any of the data files
~ edit
i'm attaching my build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="HELL scream" default="all" basedir=".">
<property name="build.sources.dir" location="${basedir}/src"/>
<property name="build.sources.des" location="${basedir}/bin/classes"/>
<property name="test.sources.dir" location="${basedir}/src_test"/>
<property name="test.sources.des" location="${basedir}/bin/classes_test"/>
<property name="test.reports.des" location="${basedir}/reports-junit"/>
<property name="emma.sources.des" location="${basedir}/bin/classes_emma"/>
<property name="emma.reports.des" location="${basedir}/reports-emma"/>
<property name="emma.final.reports.des" location="${basedir}/reports-emma/final"/>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<path id="emma.lib" >
<fileset dir="/home/user1/Desktop/emma-2.0.5312/lib">
<include name="*.jar"/>
</fileset>
</path>
<taskdef resource="emma_ant.properties" classpathref="emma.lib" />
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<target name="clean-all">
<delete failonerror="false">
<fileset dir="${emma.final.reports.des}"/>
<fileset dir="${emma.reports.des}"/>
<fileset dir="${emma.sources.des}"/>
<fileset dir="${test.reports.des}"/>
<fileset dir="${test.sources.des}"/>
<fileset dir="${build.sources.des}"/>
</delete>
</target>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<target name="compile-sources">
<mkdir dir="${build.sources.des}"/>
<javac srcdir="${build.sources.dir}" includes="" excludes="" destdir="${build.sources.des}" listfiles="true" debug="true" includeantruntime="false"/>
</target>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<target name="compile-tests">
<mkdir dir="${test.sources.des}"/>
<javac srcdir="${test.sources.dir}" includes="" excludes="" destdir="${test.sources.des}" listfiles="true" debug="true" includeantruntime="false">
<classpath>
<pathelement location="/home/user1/Desktop/junit-4.10.jar"/>
<pathelement location="${build.sources.des}"/>
</classpath>
</javac>
</target>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<target name="compile-emma-tests">
<emma enabled="true" >
<instr instrpath="${test.sources.des}" destdir="${emma.sources.des}" metadatafile ="${emma.reports.des}/instrumentation.emma" merge ="true"/>
</emma>
</target>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<target name="run-tests">
<mkdir dir="${test.reports.des}"/>
<junit haltonfailure="no" showoutput="yes" printsummary="true">
<formatter type="plain" usefile="false" />
<formatter type="xml"/>
<classpath>
<pathelement location="/home/user1/Desktop/junit-4.10.jar"/>
<pathelement location="${build.sources.des}"/>
<pathelement location="${emma.sources.des}"/>
<path refid="emma.lib" />
</classpath>
<batchtest todir="${test.reports.des}" fork="true">
<fileset dir="${emma.sources.des}"/>
</batchtest>
<jvmarg value="-Demma.coverage.out.file=${emma.reports.des}/coverage.emma" />
<jvmarg value="-Demma.coverage.out.merge=false" />
</junit>
</target>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<target name="junit-tests-report">
<junitreport todir="${test.reports.des}">
<fileset dir="${test.reports.des}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${test.reports.des}/junit_reports"/>
</junitreport>
</target>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<target name="emma-tests-report">
<emma enabled="true" >
<report sourcepath="${build.sources.dir}">
<fileset dir="${emma.reports.des}" >
<include name="*.emma" />
</fileset>
<txt outfile="${emma.final.reports.des}/coverage.txt" depth="package" columns="class,method,block,line,name" />
<xml outfile="${emma.final.reports.des}/coverage.xml" depth="package" />
<html outfile="${emma.final.reports.des}/coverage.html" depth="method" columns="name,class,method,block,line" />
</report>
</emma>
</target>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<target name="all" depends="clean-all, compile-sources, compile-tests, compile-emma-tests, run-tests, junit-tests-report, emma-tests-report"/>
</project>
it is probably something trivial...
also, when using emma.sources.dest
i'm getting this on my (only) test
run-tests:
[junit] Running com.emma.test.MathTest
[junit] Testsuite: com.emma.test.MathTest
[junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
[junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
[junit]
[junit] Caused an ERROR
[junit] Illegal local variable table length 5 in method com.emma.test.MathTest.<init>()V
[junit] java.lang.ClassFormatError: Illegal local variable table length 5 in method com.emma.test.MathTest.<init>()V
[junit] at java.lang.Class.forName0(Native Method)
[junit] at java.lang.Class.forName(Class.java:188)
[junit]
[junit] Test com.emma.test.MathTest FAILED
~ SOLVED
add this:
<jvmarg value="-XX:-UseSplitVerifier"/>
<jvmarg value="-Demma.coverage.out.file=${emma.reports.des}/coverage.emma" />
<jvmarg value="-Demma.coverage.out.merge=false" />
Emma hasn't had a stable release since 2005, and doesn't play well with newer versions of the JDKs. Cobertura hasn't done any new development since 2011.
Because of that, I no longer recommend to developers to use Emma or Cobertura.
I've switched to JaCoCo for code coverage. It was started by the Emma Eclipse team, and is actively being developed.
As stated in JaCoCo's mission statement.
[...]Two of the best and widely used available open source tools are EMMA and Cobertura. Both tools are not actively maintained by the original authors any more and do not support the current Java versions. Due to the lack of regression tests maintenance and feature additions is difficult.
Therefore we started the JaCoCo project to provide a new standard technology for code coverage analysis in Java VM based environments. [...]
The nice thing about JaCoCo is that it works in a wide variety of environments, and you don't have to instrument your code after compiling. The instrumentation takes place as the tests are being executed. It looks something like this:
<jacoco:coverage destfile="${target.dir}/jacoco.exec">
<junit>
[...]
</junit>
</jacoco>
You then use <jacoco:coverage> to print the coverage report.
Do you have to use Emma? If not, you might better luck getting everything working using JaCoCo.
Emma relies upon bytecode injection (if memory serves me well); but, with Java 7, the code hasn't been updated because the JVM now has a debugging interface.
JaCoCo tests code coverage by attaching to the debugging interface and listening as your code enters methods and passes over the bytecode without injecting checkpoints. It's clearly the superior way to do things (now that it exists) and I doubt that Emma will do the work to fully support Java 7.
I suggest that you "upgrade" to JaCoCo.
You get this error when you use wrong command to generate the report.
Most of the online tutorial is advocating the wrong(may by old) command, even I got this error when I used below command to generate the report:
{JAVA_HOME}\jre\lib\ext>java -cp emma.jar emma report -r html -in coverage.em, {ALFRESCO_HOME}\coverage.ec
EMMA: processing input files ...
EMMA: 1 file(s) read and merged in 60 ms
EMMA: nothing to do: no runtime coverage data found in any of the data files
Correct usage of the command is:
{JAVA_HOME}\jre\lib\ext>java -cp emma.jar emma report -r txt,html -in {JAVA_HOME}\jre\lib\ext\coverage.em -in C:\t1_tempSetup\Alfresco\coverage.ec
EMMA: processing input files ...
EMMA: 2 file(s) read and merged in 70 ms
EMMA: writing [txt] report to [{JAVA_HOME}\jre\lib\ext\coverage.txt] ...
EMMA: writing [html] report to [{JAVA_HOME}\jre\lib\ext\coverage\index.html] ...

Junit + Ant + Eclipse unit test attempts to run but always returns 1 execution

I have an ant task that I am running via Eclipse that fails to properly execute the test case. The output from Ant is as follows:
[junit] Running my.custom.test.GoTest
[junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 seconds
[junit] Test my.custom.test.GoTest FAILED
Ant script minimum possible:
<project>
<target name="test">
<javac srcdir="Test/src" destdir="Test/bin" />
<junit fork="true" printsummary="true">
<batchtest>
<fileset dir="Test/test">
<include name="**/*Test.*"/>
</fileset>
</batchtest>
</junit>
</target>
</project>
Java file:
package my.custom.test
public class GoTest
{
#Test
public void test_1() throws Exception
{
assertTrue(true);
}
#Test
public void test_2() throws Exception
{
assertFalse(false);
}
}
I expect the output above from the ant junit task to produce two tests being run. However, only one is being run. I am looking for any reasoning as to why this would happen or if there is a configuration issue that I am missing.
In case someone else runs into this exact same issue or something very similar the following change will be of great benefit:
<junit fork="true" printsummary="true">
<formatter type="plain" usefile="false" />
<batchtest>
<fileset dir="Test/test">
<include name="**/*Test.*"/>
</fileset>
</batchtest>
</junit>
This led me to a ClassNotFoundException

New to Ant, ClassNotFoundException with JUnit

I've been scratching my head over this for a while now (Googled a bunch, looked through other related SO posts to no avail). I have a Java program comprised of two files, Logic and Tests. Tests contains about a hundred JUnit tests, and I've gotten 100% success rate with said tests by calling javac *.java followed by java org.junit.runner.JUnitCore Tests. However when I run my build.xml with a simple ant -verbose test (in order to follow the output since I'm new to all this), I get the following output:
[junit] Testsuite: Tests
[junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec
[junit]
[junit] Null Test: Caused an ERROR
[junit] Tests
[junit] java.lang.ClassNotFoundException: Tests
[junit] at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
[junit] at java.lang.Class.forName0(Native Method)
[junit] at java.lang.Class.forName(Class.java:247)
[junit]
[junit]
[junit] Test Tests FAILED
BUILD SUCCESSFUL
My build.xml is as follows:
<project name="ETL_Automation" default="test" basedir=".">
<path id="classpath.base">
</path>
<path id="classpath.test">
<pathelement location="${basedir}/mysql-connector-java-5.1.18-bin.jar" />
<pathelement location="${basedir}/junit-4.10.jar"/>
<path refid="classpath.base" />
</path>
<target name="compile">
<javac srcdir="${basedir}">
<classpath refid="classpath.test"/>
</javac>
</target>
<target name="test" depends="compile">
<junit fork="no">
<classpath refid="classpath.test" />
<formatter type="brief" usefile="false" />
<batchtest>
<fileset dir="${basedir}/" includes="Tests.class" />
</batchtest>
</junit>
</target>
<target name="clean" depends="test">
<delete>
<fileset dir="${basedir}" includes="*.class"/>
</delete>
</target>
The directory structure is pretty straightforward. Tests.java, Logic.java, junit-4.10.jar, mysql-connector-java-5.1.18-bin.jar, build.xml, and a referenced .properties file are all in the same folder. The java code references external files but those are unrelated to this particular issue. I don't know if the classpath could be the cause of this issue (as I'm pretty convinced what I currently have doesn't work).
Thanks!
You will need to add the directory with the Tests.class to the classpath.tests classpath (which is ${basedir} in your setup)
Try:
<path id="classpath.test">
<pathelement location="${basedir}/mysql-connector-java-5.1.18-bin.jar" />
<pathelement location="${basedir}/junit-4.10.jar"/>
<pathelement location="${basedir}" />
<path refid="classpath.base" />
</path>

How do I configure JUnit Ant task to only produce output on failures?

I am configuring JUnit in Ant so that unit tests will be run on each build. I would like the output of failing tests to be printed in the Ant console output whenever they are run. I don't need to see any output from succeeding tests.
Here is the relevant bit of my build.xml file:
<junit>
<classpath>
<pathelement path="${build}"/>
</classpath>
<formatter type="brief" usefile="false"/>
<batchtest>
<fileset dir="${src}" includes="my/tree/junit/"/>
</batchtest>
</junit>
This produces almost what I want, failing tests are detailed in the Ant output, except that succeeding tests also write the following output:
[junit] Testsuite: my.tree.junit.ExampleTest
[junit] Tests run: 7, Failures: 0, Errors: 0, Time elapsed: 0.002 sec
I believe I have tried all the combinations listed in the JUnit task documentation, including:
printsummary attribute
showoutput attribute
formatter element with each kind of type
My use case is running ant from the command line. As I write more tests, I don't want the output from succeeding tests to be so large that output from failing tests scrolls off the screen. I just want ant to be quiet unless there's a failing test that needs my attention. How can I configure Ant/JUnit to do this?
I am using Ant version 1.6.4 and JUnit 4.6.
One possibility would be to define your own xml formatter with the 'classname' attribute (and extending org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter, potentially doing nothing on endTest() or endTestsuite() methods).
That formatter would ignore info message and only display failure messages.
Note: this settings mention the possibility of only displaying failed tests:
<junit showoutput="true"
fork="true"
failureproperty="tests.failed"
errorproperty="tests.failed">
<batchtest todir="${test.results.dir}">
<fileset dir="test">
<include name="**/*Test.java"/>
</fileset>
</batchtest>
<classpath path="${classes.dir}:${junit.jar}:${test.classes.dir}"/>
<formatter usefile="false" type="brief"/>
<!-- <formatter type="xml"/> If missing, only displays failed tests -->
</junit>
Did you test that ?
Note: the "showoutput="true" and <formatter type="brief" usefile="false"/>" can be a bit problematic, as illustrated by this recent (February 2012) ticket)
Yet another approch would be to define your ant Juint Test runner, supporting ant JUnitResultFormatter and displaying only stderr messages.
The EclipseTestRunner from eclipse is a good example.

Categories