org.testng.junit.JUnit4TestRunner Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of testng Show documentation
Show all versions of testng Show documentation
Testing framework for Java
package org.testng.junit;
import java.util.*;
import java.util.regex.Pattern;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
import org.junit.runner.Request;
import org.junit.runner.Result;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import org.testng.*;
import org.testng.collections.Lists;
import org.testng.internal.ITestResultNotifier;
import org.testng.internal.InvokedMethod;
import org.testng.internal.TestResult;
/**
* A JUnit TestRunner that records/triggers all information/events necessary to TestNG.
*
* @author Lukas Jungmann
*/
public class JUnit4TestRunner implements IJUnitTestRunner {
private ITestResultNotifier m_parentRunner;
private List m_methods = Lists.newArrayList();
private List m_listeners = Lists.newArrayList();
private Collection m_invokeListeners = Lists.newArrayList();
private Map m_findedMethods = new WeakHashMap<>();
public JUnit4TestRunner() {}
public JUnit4TestRunner(ITestResultNotifier tr) {
m_parentRunner = tr;
m_listeners = m_parentRunner.getTestListeners();
}
/**
* Needed from TestRunner in order to figure out what JUnit test methods were run.
*
* @return the list of all JUnit test methods run
*/
@Override
public List getTestMethods() {
return m_methods;
}
@Override
public void setTestResultNotifier(ITestResultNotifier notifier) {
m_parentRunner = notifier;
m_listeners = m_parentRunner.getTestListeners();
}
public void setInvokedMethodListeners(Collection listeners) {
m_invokeListeners = listeners;
}
/**
* A start
implementation that ignores the TestResult
*
* @param testClass the JUnit test class
*/
@Override
public void run(Class testClass, String... methods) {
start(testClass, methods);
}
/** Starts a test run. Analyzes the command line arguments and runs the given test suite. */
public Result start(final Class testCase, final String... methods) {
try {
JUnitCore core = new JUnitCore();
core.addListener(new RL());
Request r = Request.aClass(testCase);
return core.run(
r.filterWith(
new Filter() {
@Override
public boolean shouldRun(Description description) {
if (description == null) {
return false;
}
if (methods.length == 0) {
if (description.getTestClass() != null) {
ITestResult tr = createTestResult(description);
m_findedMethods.put(description, tr);
}
// run everything
return true;
}
for (String m : methods) {
Pattern p = Pattern.compile(m);
if (p.matcher(description.getMethodName()).matches()) {
ITestResult tr = createTestResult(description);
m_findedMethods.put(description, tr);
return true;
}
}
return false;
}
@Override
public String describe() {
return "TestNG method filter";
}
}));
} catch (Throwable t) {
throw new TestNGException("Failure in JUnit mode for class " + testCase.getName(), t);
}
}
private class RL extends RunListener {
private List notified = new LinkedList<>();
@Override
public void testAssumptionFailure(Failure failure) {
notified.add(failure.getDescription());
ITestResult tr = m_findedMethods.get(failure.getDescription());
validate(tr, failure.getDescription());
runAfterInvocationListeners(tr);
tr.setStatus(TestResult.SKIP);
tr.setEndMillis(Calendar.getInstance().getTimeInMillis());
tr.setThrowable(failure.getException());
m_parentRunner.addSkippedTest(tr.getMethod(), tr);
for (ITestListener l : m_listeners) {
l.onTestSkipped(tr);
}
}
@Override
public void testFailure(Failure failure) throws Exception {
if (failure == null) {
return;
}
if (isAssumptionFailed(failure)) {
this.testAssumptionFailure(failure);
return;
}
notified.add(failure.getDescription());
ITestResult tr = m_findedMethods.get(failure.getDescription());
if (tr == null) {
// Not a test method, should be a config
tr = createTestResult(failure.getDescription());
runAfterInvocationListeners(tr);
tr.setStatus(TestResult.FAILURE);
tr.setEndMillis(Calendar.getInstance().getTimeInMillis());
tr.setThrowable(failure.getException());
for (IConfigurationListener l : m_parentRunner.getConfigurationListeners()) {
l.onConfigurationFailure(tr);
}
for (Description childDesc : failure.getDescription().getChildren()) {
testIgnored(childDesc);
}
} else {
runAfterInvocationListeners(tr);
tr.setStatus(TestResult.FAILURE);
tr.setEndMillis(Calendar.getInstance().getTimeInMillis());
tr.setThrowable(failure.getException());
m_parentRunner.addFailedTest(tr.getMethod(), tr);
for (ITestListener l : m_listeners) {
l.onTestFailure(tr);
}
}
}
@Override
public void testFinished(Description description) throws Exception {
ITestResult tr = m_findedMethods.get(description);
validate(tr, description);
runAfterInvocationListeners(tr);
if (!notified.contains(description)) {
tr.setStatus(TestResult.SUCCESS);
tr.setEndMillis(Calendar.getInstance().getTimeInMillis());
m_parentRunner.addPassedTest(tr.getMethod(), tr);
for (ITestListener l : m_listeners) {
l.onTestSuccess(tr);
}
}
m_methods.add(tr.getMethod());
}
@Override
public void testIgnored(Description description) throws Exception {
if (!notified.contains(description)) {
notified.add(description);
ITestResult tr = m_findedMethods.get(description);
validate(tr, description);
runAfterInvocationListeners(tr);
tr.setStatus(TestResult.SKIP);
tr.setEndMillis(tr.getStartMillis());
m_parentRunner.addSkippedTest(tr.getMethod(), tr);
m_methods.add(tr.getMethod());
for (ITestListener l : m_listeners) {
l.onTestSkipped(tr);
}
}
}
@Override
public void testRunFinished(Result result) throws Exception {}
@Override
public void testRunStarted(Description description) throws Exception {}
@Override
public void testStarted(Description description) throws Exception {
ITestResult tr = m_findedMethods.get(description);
validate(tr, description);
for (ITestListener l : m_listeners) {
l.onTestStart(tr);
}
}
private void runAfterInvocationListeners(ITestResult tr) {
InvokedMethod im =
new InvokedMethod(tr.getTestClass(), tr.getMethod(), tr.getEndMillis(), tr);
for (IInvokedMethodListener l : m_invokeListeners) {
l.afterInvocation(im, tr);
}
}
private void validate(ITestResult tr, Description description) {
if (tr == null) {
throw new TestNGException(stringify(description));
}
}
private String stringify(Description description) {
return description.getClassName() + "." + description.getMethodName() + "()";
}
}
private ITestResult createTestResult(Description test) {
JUnit4TestClass tc = new JUnit4TestClass(test);
JUnitTestMethod tm = new JUnit4TestMethod(tc, test);
TestResult tr = TestResult.newTestResultFor(tm);
InvokedMethod im =
new InvokedMethod(tr.getTestClass(), tr.getMethod(), tr.getStartMillis(), tr);
m_parentRunner.addInvokedMethod(im);
for (IInvokedMethodListener l : m_invokeListeners) {
l.beforeInvocation(im, tr);
}
return tr;
}
private static boolean isAssumptionFailed(Failure failure) {
//noinspection ThrowableResultOfMethodCallIgnored
final Throwable exception = failure.getException();
//noinspection SimplifiableIfStatement
if (exception == null) {
return false;
}
return "org.junit.internal.AssumptionViolatedException"
.equals(exception.getClass().getCanonicalName());
}
}