package org.junit.tests.running.classes;
import static org.junit.Assert.fail;
import java.util.List;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Categories.CategoryFilter;
import org.junit.experimental.categories.Category;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
import org.junit.runner.Request;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.junit.runners.model.Statement;
/**
* Tests verifying that class-level fixtures ({@link BeforeClass} and
* {@link AfterClass}) and rules ({@link ClassRule}) are not executed when there
* are no test methods to be run in a test class because they have been ignored.
*
*/
public class ClassLevelMethodsWithIgnoredTestsTest {
private static final String FAILURE_MESSAGE = "This should not have happened!";
public static class BeforeClassWithIgnoredTest {
@BeforeClass
public static void beforeClass() {
fail(FAILURE_MESSAGE);
}
@Ignore
@Test
public void test() throws Exception {
fail("test() should not run");
}
}
@Test
public void beforeClassShouldNotRunWhenAllTestsAreIgnored() {
runClassAndVerifyNoFailures(BeforeClassWithIgnoredTest.class,
"BeforeClass should not have been executed because the test method is ignored!");
}
@Ignore
public static class BeforeClassWithIgnoredClass {
@BeforeClass
public static void beforeClass() {
fail(FAILURE_MESSAGE);
}
@Test
public void test() throws Exception {
fail("test() should not run");
}
}
@Test
public void beforeClassShouldNotRunWhenWholeClassIsIgnored() {
runClassAndVerifyNoFailures(
BeforeClassWithIgnoredClass.class,
"BeforeClass should not have been executed because the whole test class is ignored!");
}
public static class AfterClassWithIgnoredTest {
@Ignore
@Test
public void test() throws Exception {
fail("test() should not run");
}
@AfterClass
public static void afterClass() {
fail(FAILURE_MESSAGE);
}
}
@Test
public void afterClassShouldNotRunWhenAllTestsAreIgnored() {
runClassAndVerifyNoFailures(AfterClassWithIgnoredTest.class,
"AfterClass should not have been executed because the test method is ignored!");
}
public interface FilteredTests {
}
public static class BeforeClassWithFilteredTest {
@BeforeClass
public static void setUpClass() {
fail(FAILURE_MESSAGE);
}
@Category(FilteredTests.class)
@Test
public void test() throws Exception {
fail("test() should not run");
}
}
public static class HasUnfilteredTest {
@Test
public void unfilteredTest() {
// to prevent errors when all other tests have been filtered
}
}
@Test
public void beforeClassShouldNotRunWhenAllTestsAreFiltered() {
Result result = new JUnitCore().run(Request.classes(
BeforeClassWithFilteredTest.class, HasUnfilteredTest.class)
.filterWith(CategoryFilter.exclude(FilteredTests.class)));
analyseResult(
result,
"BeforeClass should not have been executed because the test method is filtered!");
}
public static class BrokenRule implements TestRule {
public Statement apply(Statement base, Description description) {
throw new RuntimeException("this rule is broken");
}
}
public static class ClassRuleWithIgnoredTest {
@ClassRule
public static BrokenRule brokenRule = new BrokenRule();
@Ignore
@Test
public void test() throws Exception {
fail("test() should not be run");
}
}
@Test
public void classRuleShouldNotBeAppliedWhenAllTestsAreIgnored() {
runClassAndVerifyNoFailures(ClassRuleWithIgnoredTest.class,
"The class rule should have been applied because the test method is ignored!");
}
private void runClassAndVerifyNoFailures(Class<?> klass,
String testFailureDescription) {
Result result = JUnitCore.runClasses(klass);
analyseResult(result, testFailureDescription);
}
private void analyseResult(Result result, String testFailureDescription) {
List<Failure> failures = result.getFailures();
if (failures.isEmpty() == false) {
analyzeFailure(failures.get(0), testFailureDescription);
}
}
private void analyzeFailure(Failure failure, String testFailureDescription) {
String actualFailureMsg = failure.getMessage();
if (FAILURE_MESSAGE.equals(actualFailureMsg)) {
fail(testFailureDescription);
}
fail("Unexpected failure : " + actualFailureMsg);
}
}