package ru.yandex.qatools.allure.junit;
import org.junit.Ignore;
import org.junit.internal.AssumptionViolatedException;
import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import ru.yandex.qatools.allure.Allure;
import ru.yandex.qatools.allure.config.AllureModelUtils;
import ru.yandex.qatools.allure.events.ClearStepStorageEvent;
import ru.yandex.qatools.allure.events.TestCaseCanceledEvent;
import ru.yandex.qatools.allure.events.TestCaseFailureEvent;
import ru.yandex.qatools.allure.events.TestCaseFinishedEvent;
import ru.yandex.qatools.allure.events.TestCasePendingEvent;
import ru.yandex.qatools.allure.events.TestCaseStartedEvent;
import ru.yandex.qatools.allure.events.TestSuiteFinishedEvent;
import ru.yandex.qatools.allure.events.TestSuiteStartedEvent;
import ru.yandex.qatools.allure.utils.AnnotationManager;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* @author Dmitry Baev charlie@yandex-team.ru
* Date: 20.12.13
*/
public class AllureRunListener extends RunListener {
private Allure lifecycle = Allure.LIFECYCLE;
private final Map<String, String> suites = new HashMap<>();
@Override
public void testRunStarted(Description description) {
if (description == null) {
// If you don't pass junit provider - surefire (<= 2.17) pass null instead of description
return;
}
for (Description suite : description.getChildren()) {
testSuiteStarted(suite);
}
}
public void testSuiteStarted(Description description) {
String uid = generateSuiteUid(description.getClassName());
TestSuiteStartedEvent event = new TestSuiteStartedEvent(uid, description.getClassName());
AnnotationManager am = new AnnotationManager(description.getAnnotations());
am.update(event);
event.withLabels(AllureModelUtils.createTestFrameworkLabel("JUnit"));
getLifecycle().fire(event);
}
@Override
public void testStarted(Description description) {
TestCaseStartedEvent event = new TestCaseStartedEvent(getSuiteUid(description), description.getMethodName());
AnnotationManager am = new AnnotationManager(description.getAnnotations());
am.update(event);
fireClearStepStorage();
getLifecycle().fire(event);
}
@Override
public void testFailure(Failure failure) {
if (failure.getDescription().isTest()) {
fireTestCaseFailure(failure.getException());
} else {
startFakeTestCase(failure.getDescription());
fireTestCaseFailure(failure.getException());
finishFakeTestCase();
}
}
@Override
public void testAssumptionFailure(Failure failure) {
testFailure(failure);
}
@Override
public void testIgnored(Description description) {
startFakeTestCase(description);
getLifecycle().fire(new TestCasePendingEvent().withMessage(getIgnoredMessage(description)));
finishFakeTestCase();
}
@Override
public void testFinished(Description description) {
getLifecycle().fire(new TestCaseFinishedEvent());
}
public void testSuiteFinished(String uid) {
getLifecycle().fire(new TestSuiteFinishedEvent(uid));
}
@Override
public void testRunFinished(Result result) {
for (String uid : getSuites().values()) {
testSuiteFinished(uid);
}
}
public String generateSuiteUid(String suiteName) {
String uid = UUID.randomUUID().toString();
synchronized (getSuites()) {
getSuites().put(suiteName, uid);
}
return uid;
}
public String getSuiteUid(Description description) {
String suiteName = description.getClassName();
if (!getSuites().containsKey(suiteName)) {
Description suiteDescription = Description.createSuiteDescription(description.getTestClass());
testSuiteStarted(suiteDescription);
}
return getSuites().get(suiteName);
}
public String getIgnoredMessage(Description description) {
Ignore ignore = description.getAnnotation(Ignore.class);
return ignore == null || ignore.value().isEmpty() ? "Test ignored (without reason)!" : ignore.value();
}
public void startFakeTestCase(Description description) {
String uid = getSuiteUid(description);
String name = description.isTest() ? description.getMethodName() : description.getClassName();
TestCaseStartedEvent event = new TestCaseStartedEvent(uid, name);
AnnotationManager am = new AnnotationManager(description.getAnnotations());
am.update(event);
fireClearStepStorage();
getLifecycle().fire(event);
}
public void finishFakeTestCase() {
getLifecycle().fire(new TestCaseFinishedEvent());
}
public void fireTestCaseFailure(Throwable throwable) {
if (throwable instanceof AssumptionViolatedException) {
getLifecycle().fire(new TestCaseCanceledEvent().withThrowable(throwable));
} else {
getLifecycle().fire(new TestCaseFailureEvent().withThrowable(throwable));
}
}
public void fireClearStepStorage() {
getLifecycle().fire(new ClearStepStorageEvent());
}
public Allure getLifecycle() {
return lifecycle;
}
public void setLifecycle(Allure lifecycle) {
this.lifecycle = lifecycle;
}
public Map<String, String> getSuites() {
return suites;
}
}