blob: 36da245adeff8de8bc1293fb7f2718f914331b83 [file] [log] [blame]
/*
* Copyright 2000-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package tools.JUnit;
import java.io.*;
import java.text.NumberFormat;
import java.util.*;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.optional.junit.*;
/**
* Prints plain text output of the test to a specified Writer.
*
* @author Stefan Bodewig
*/
public class SimpleResultFormatter implements JUnitResultFormatter {
public static int TEST_SUCCESS = 0;
public static int TEST_FAILURE = 1;
public static int TEST_ERROR = 2;
public static int TEST_UNKNOWN = 3;
// Lets capture STDOUT and STDERR
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
ByteArrayOutputStream bErr = new ByteArrayOutputStream();
PrintStream _out;
PrintStream _err;
private TestRecord testRecord;
Collection records;
/**
* Formatter for timings.
*/
private NumberFormat nf = NumberFormat.getInstance();
/**
* Timing helper.
*/
private Hashtable testStarts = new Hashtable();
/**
* Where to write the log to.
*/
private OutputStream out;
/**
* Helper to store intermediate output.
*/
private StringWriter inner;
/**
* Convenience layer on top of {@link #inner inner}.
*/
private PrintWriter wri;
/**
* Suppress endTest if testcase failed.
*/
private Hashtable failed = new Hashtable();
private String systemOutput = null;
private String systemError = null;
public SimpleResultFormatter() {
inner = new StringWriter();
wri = new PrintWriter(inner);
}
public void setOutput(OutputStream out) {
this.out = out;
}
public void setSystemOutput(String out) {
// We will be capturing Stdout and Stderr internally so this is
// redundant
//systemOutput = out;
}
public void setSystemError(String err) {
// We will be capturing Stdout and Stderr internally so this is
// redundant
//systemError = err;
}
/**
* Signals starting of a Suite of tests
*/
public void startTestSuite(JUnitTest suite) {
records = new ArrayList();
}
/**
* The whole testsuite ended.
*/
public void endTestSuite(JUnitTest suite) throws BuildException {
String newLine = System.getProperty("line.separator");
StringBuilder sb = new StringBuilder("Testsuite: ");
sb.append(suite.getName());
sb.append(newLine);
sb.append("Tests run: ");
sb.append(suite.runCount());
sb.append(", Failures: ");
sb.append(suite.failureCount());
sb.append(", Errors: ");
sb.append(suite.errorCount());
sb.append(", Time elapsed: ");
sb.append(nf.format(suite.getRunTime() / 1000.0));
sb.append(" sec");
sb.append(newLine);
//sb.append("DEBUG: " + records.size());
sb.append("======================================================");
Iterator it = records.iterator();
while (it.hasNext())
{
TestRecord rec = (TestRecord) it.next();
sb.append(newLine);
sb.append("Test: " + rec.getTestname()).append(newLine);
sb.append("Result: " + rec.getStatusString()).append(newLine);
float diff = rec.getEndTime() - rec.getStartTime();
sb.append("Start time: " + rec.getStartTime()).append(newLine);
sb.append("End time : " + rec.getEndTime()).append(newLine);
sb.append("Execution time: " + diff/1000).append(newLine);
sb.append("[STDOUT]").append(newLine);
sb.append(rec.getSysout()).append(newLine);
sb.append("[STDERR]").append(newLine);
sb.append(rec.getSyserr()).append(newLine);
if (rec.isFailure())
{
sb.append("[EXCEPTION]").append(newLine);
sb.append(JUnitTestRunner.getFilteredTrace(rec.getThrowable()));
sb.append(newLine);
}
sb.append("======================================================");
}
/*
// append the err and output streams to the log
if (systemOutput != null && systemOutput.length() > 0) {
sb.append("------------- Standard Output ---------------")
.append(newLine)
.append(systemOutput)
.append("------------- ---------------- ---------------")
.append(newLine);
}
if (systemError != null && systemError.length() > 0) {
sb.append("------------- Standard Error -----------------")
.append(newLine)
.append(systemError)
.append("------------- ---------------- ---------------")
.append(newLine);
}
sb.append(newLine);
*/
if (out != null) {
try {
out.write(sb.toString().getBytes());
wri.close();
//out.write(inner.toString().getBytes());
out.flush();
} catch (IOException ioex) {
throw new BuildException("Unable to write output", ioex);
} finally {
if (out != System.out && out != System.err) {
try {
out.close();
} catch (IOException e) {
// ignore
}
}
}
}
}
/**
* Interface TestListener.
*
* <p>A new Test is started.
*/
public void startTest(Test t) {
// Lets start the capture
System.out.flush();
System.err.flush();
_out = System.out;
_err = System.err;
bOut.reset();
bErr.reset();
System.setOut(new PrintStream(bOut));
System.setErr(new PrintStream(bErr));
// Store the previous record
testRecord = new TestRecord(t.toString());
testRecord.setStartTime(System.currentTimeMillis());
testStarts.put(t, new Long(System.currentTimeMillis()));
failed.put(t, Boolean.FALSE);
}
/**
* Interface TestListener.
*
* <p>A Test is finished.
*/
public void endTest(Test test) {
long endTime = System.currentTimeMillis();
System.out.flush();
System.err.flush();
// Update the test record
testRecord.setSysout(bOut.toString());
testRecord.setSyserr(bErr.toString());
testRecord.setEndTime(endTime);
// If the test did not fail, record it as a success
if (!testRecord.isFailure())
testRecord.setStatus(TEST_SUCCESS);
// Add it to the set
records.add(testRecord);
System.setOut(_out);
System.setErr(_err);
}
/**
* Interface TestListener for JUnit &gt; 3.4.
*
* <p>A Test failed.
*/
public void addFailure(Test test, AssertionFailedError t) {
//addFailure(test, (Throwable) t);
testRecord.setStatus(TEST_FAILURE);
testRecord.setThrowable(t);
// Record end time now..
}
/**
* Interface TestListener.
*
* <p>An error occured while running the test.
*/
public void addError(Test test, Throwable t) {
testRecord.setStatus(TEST_ERROR);
testRecord.setThrowable(t);
}
/**
* Utility class to record per test data like test name, status, start
* and end time, STDOUT, STDERR from text execution etc.
*/
private class TestRecord
{
public TestRecord(String name)
{
setTestname(name);
}
private String testname;
private String sysout;
private String syserr;
private Throwable t;
private long startTime;
private long endTime;
private int status;
boolean failed = false;
private String testUnitName;
private String testLogicalName;
public void setTestname(String name)
{
this.testname = name;
}
public String getTestname()
{
return testname;
}
public void setStatus(int status)
{
this.status = status;
if (status == TEST_ERROR || status == TEST_FAILURE)
failed = true;
}
public int getStatus()
{
return status;
}
public String getStatusString()
{
return (status == TEST_SUCCESS)?"SUCCESS":
(status == TEST_ERROR)?"ERROR":"FAILURE";
}
public boolean isFailure()
{
return failed;
}
public String getSysout()
{
return sysout;
}
public void setSysout(String sysout)
{
this.sysout = sysout;
}
public String getSyserr()
{
return syserr;
}
public void setSyserr(String syserr)
{
this.syserr = syserr;
}
public Throwable getThrowable()
{
return t;
}
public void setThrowable(Throwable t)
{
this.t = t;
}
public long getStartTime()
{
return startTime;
}
public void setStartTime(long startTime)
{
this.startTime = startTime;
}
public long getEndTime()
{
return endTime;
}
public void setEndTime(long endTime)
{
this.endTime = endTime;
}
}
} // PlainJUnitResultFormatter