6

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?

user11171
  • 3,821
  • 5
  • 26
  • 35

2 Answers2

7

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.

user11171
  • 3,821
  • 5
  • 26
  • 35
2

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?

Community
  • 1
  • 1
dkatzel
  • 31,188
  • 3
  • 63
  • 67
  • Thank you for this answer. I've added my own answer with the code I used to get this to work since I think the example you linked to is unnecessarily long. – user11171 Aug 22 '13 at 16:29