package test_streamer.client;
import junit.framework.AssertionFailedError;
import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import test_streamer.client.dto.ErrorResult;
import test_streamer.client.dto.FailureResult;
import test_streamer.client.dto.TestSuiteResult;
import test_streamer.client.dto.TestCaseResult;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
/**
* @author kawasima
*/
public class ClientRunListener extends RunListener {
private Map<String, TestCaseResult> runningCases = new HashMap<String, TestCaseResult>();
private Map<String, Long> runningTimes = new HashMap<String, Long>();
private Long suiteStartedTime;
private TestSuiteResult suiteResult;
public ClientRunListener(String name) {
suiteResult = new TestSuiteResult(name);
}
public TestSuiteResult getResult() {
return suiteResult;
}
private String extractStackTrace(Throwable t) {
StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw));
return sw.toString();
}
@Override
public void testRunStarted(Description description) throws Exception {
description.getChildren().get(0);
suiteStartedTime = System.currentTimeMillis();
}
/**
* Called when an atomic test is about to be started.
*
* @param description the description of the test that is about to be run
* (generally a class and method name)
*/
@Override
public void testStarted(Description description) throws Exception {
TestCaseResult testCaseResult = new TestCaseResult();
testCaseResult.setClassname(description.getClassName());
testCaseResult.setName(description.getMethodName());
runningCases.put(description.getDisplayName(), testCaseResult);
runningTimes.put(description.getDisplayName(), System.currentTimeMillis());
}
/**
* Called when an atomic test has finished, whether the test succeeds or fails.
*
* @param description the description of the test that just ran
*/
public void testFinished(Description description) throws Exception {
suiteResult.incrementTests();
TestCaseResult testCaseResult = runningCases.remove(description.getDisplayName());
Long startTime = runningTimes.remove(description.getDisplayName());
testCaseResult.setTime((System.currentTimeMillis() - startTime) / 1000f);
suiteResult.getTestcases().add(testCaseResult);
}
/**
* Called when an atomic test fails.
*
* @param failure describes the test that failed and the exception that was thrown
*/
public void testFailure(Failure failure) throws Exception {
TestCaseResult testCaseResult = runningCases.get(failure.getDescription().getDisplayName());
Throwable t = failure.getException();
if (t instanceof AssertionError || t instanceof AssertionFailedError) {
suiteResult.incrementFailures();
FailureResult failureResult = new FailureResult(
failure.getException().getClass(),
failure.getMessage(),
extractStackTrace(failure.getException())
);
testCaseResult.setFailure(failureResult);
} else if (Modifier.isAbstract(failure.getDescription().getTestClass().getModifiers())) {
suiteResult.incrementSkipped();
testCaseResult.setSkip(true);
} else {
suiteResult.incrementErrors();
ErrorResult errorResult = new ErrorResult(
failure.getException().getClass(),
failure.getMessage(),
extractStackTrace(failure.getException())
);
testCaseResult.setError(errorResult);
}
}
/**
* Called when an atomic test flags that it assumes a condition that is
* false
*
* @param failure describes the test that failed and the
* {@link org.junit.internal.AssumptionViolatedException} that was thrown
*/
public void testAssumptionFailure(Failure failure) {
suiteResult.incrementFailures();
TestCaseResult testCaseResult = runningCases.get(failure.getDescription().getDisplayName());
FailureResult failureResult = new FailureResult(
failure.getException().getClass(),
failure.getMessage(),
extractStackTrace(failure.getException())
);
testCaseResult.setFailure(failureResult);
}
/**
* Called when a test will not be run, generally because a test method is annotated
* with {@link org.junit.Ignore}.
*
* @param description describes the test that will not be run
*/
public void testIgnored(Description description) throws Exception {
TestCaseResult testCaseResult = runningCases.get(description.getDisplayName());
testCaseResult.setSkip(true);
suiteResult.incrementSkipped();
}
/**
* Called when all tests have finished
*
* @param result the summary of the test run, including all the tests that failed
*/
public void testRunFinished(Result result) throws Exception {
suiteResult.setTime((System.currentTimeMillis() - suiteStartedTime) / 1000f);
}
}