Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Immediate JUnit test logging with <junit> Ant Task

Tags:

junit

ant

I have the following in my build.xml:

<junit fork="yes" printsummary="yes" filtertrace="yes">
    <classpath>...</classpath>
    <test name="tests.AllTests"/>
    <formatter type="plain" usefile="false"/>
</junit>

I would like the JUnit results to be reported for each test as soon as they complete, unfortunately the JUnit task only prints the test results after the whole test case has completed. The test case (AllTests) is rather large, so I have to wait quite a while for the output. Is there any way to make <junit> print individual test results immediately?

like image 635
user11171 Avatar asked Aug 17 '13 20:08

user11171


People also ask

What happened to JUnit 4 and JUnit 5 ant?

In JUnit 5, you use the junitlauncher Ant task rather than the junit Ant task . Unfortunately, this isn’t a drop in replacement. In addition to needing a workaround to set system properties, you also need a workaround to write the test results to the console log. With JUnit 4 and Ant, you got output that looked list this for each test run.

What are the best practices for JUnit testing?

Filter out JUnit and Ant stack frames from error and failure stack traces. Overrides value set in <junit>. Directory to write the reports to. Only run tests if the named property is set. Only run tests if the named property is not set. Do not pass any classes that do not contain JUnit tests to the test runner.

What is a Classpath in Ant JUnit?

The <junit> task supports a nested <classpath> element that represents a path-like structure. Since Ant 1.7, this classpath may be used to refer to junit.jar as well as your tests and the tested code. If fork is true, additional parameters may be passed to the new JVM via nested <jvmarg> elements.

Is JUnit 4 a drop in replacement for JUnit?

Unfortunately, this isn’t a drop in replacement. In addition to needing a workaround to set system properties, you also need a workaround to write the test results to the console log. With JUnit 4 and Ant, you got output that looked list this for each test run.


2 Answers

I followed dkatzel's suggestion to write my own JUnitResultFormatter. Here is the code for my JUnitFormatter:

package util;

import java.io.OutputStream;
import java.io.PrintStream;

import junit.framework.AssertionFailedError;
import junit.framework.Test;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.optional.junit.JUnitResultFormatter;
import org.apache.tools.ant.taskdefs.optional.junit.JUnitTest;

public class SimpleTestFormatter implements JUnitResultFormatter {
    private PrintStream out = System.out;

    @Override
    public void addError(Test test, Throwable error) {
        logResult(test, "ERR");
        out.println(error.getMessage());
    }

    @Override
    public void addFailure(Test test, AssertionFailedError failure) {
        logResult(test, "FAIL");
        out.println(failure.getMessage());
    }

    @Override
    public void endTest(Test test) {
        logResult(test, "PASS");
    }

    @Override
    public void startTest(Test test) { }

    @Override
    public void endTestSuite(JUnitTest testSuite) throws BuildException { }

    @Override
    public void setOutput(OutputStream out) {
        this.out = new PrintStream(out);
    }

    @Override
    public void setSystemError(String err) {
        // don't echo test error output
    }

    @Override
    public void setSystemOutput(String out) {
        // don't echo test output
    }

    @Override
    public void startTestSuite(JUnitTest testSuite) throws BuildException { }

    private void logResult(Test test, String result) {
        out.println("[" + result + "] " + String.valueOf(test));
        out.flush();
    }
}

And this is how I use it in the Ant script:

<junit fork="yes" printsummary="yes" filtertrace="yes">
    <classpath>...</classpath>
    <test name="tests.AllTests"/>
    <formatter classname="util.SimpleTestFormatter" usefile="false"/>
</junit>

Note that the class must be compiled with ant.jar and ant-junit.jar on the classpath.

like image 179
user11171 Avatar answered Sep 30 '22 18:09

user11171


I believe the built-in JUnit formatters buffer everything until the end. You should be able to write your own formatter implementation which extends org.apache.tools.ant.taskdefs.optional.junit.JUnitResultFormatter so that it flushes to STDOUT immediately, but I've never done it.

You can use this blog where the author makes a custom formatter and shows both the code and how to use it in the build.xml http://shaman-sir.wikidot.com/one-liner-output-formatter

There is also a similar SO question with similar info How do I configure JUnit Ant task to only produce output on failures?

like image 20
dkatzel Avatar answered Sep 30 '22 19:09

dkatzel