All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.junit.experimental.categories.Categories Maven / Gradle / Ivy

Go to download

JUnit is a regression testing framework written by Erich Gamma and Kent Beck. It is used by the developer who implements unit tests in Java.

There is a newer version: 4.13.2
Show newest version
package org.junit.experimental.categories;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.junit.runner.Description;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerBuilder;

/**
 * From a given set of test classes, runs only the classes and methods that are
 * annotated with either the category given with the @IncludeCategory
 * annotation, or a subtype of that category.
 *
 * Note that, for now, annotating suites with {@code @Category} has no effect.
 * Categories must be annotated on the direct method or class.
 *
 * Example:
 *
 * 
 * public interface FastTests {
 * }
 *
 * public interface SlowTests {
 * }
 *
 * public static class A {
 *  @Test
 *  public void a() {
 *      fail();
 *     }
 *
 *  @Category(SlowTests.class)
 *  @Test
 *  public void b() {
 *     }
 * }
 *
 * @Category( { SlowTests.class, FastTests.class })
 * public static class B {
 *  @Test
 *  public void c() {
 *
 *     }
 * }
 *
 * @RunWith(Categories.class)
 * @IncludeCategory(SlowTests.class)
 * @SuiteClasses( { A.class, B.class })
 * // Note that Categories is a kind of Suite
 * public static class SlowTestSuite {
 * }
 * 
*/ public class Categories extends Suite { // the way filters are implemented makes this unnecessarily complicated, // buggy, and difficult to specify. A new way of handling filters could // someday enable a better new implementation. // https://github.com/KentBeck/junit/issues/issue/172 @Retention(RetentionPolicy.RUNTIME) public @interface IncludeCategory { public Class value(); } @Retention(RetentionPolicy.RUNTIME) public @interface ExcludeCategory { public Class value(); } public static class CategoryFilter extends Filter { public static CategoryFilter include(Class categoryType) { return new CategoryFilter(categoryType, null); } private final Class fIncluded; private final Class fExcluded; public CategoryFilter(Class includedCategory, Class excludedCategory) { fIncluded = includedCategory; fExcluded = excludedCategory; } @Override public String describe() { return "category " + fIncluded; } @Override public boolean shouldRun(Description description) { if (hasCorrectCategoryAnnotation(description)) { return true; } for (Description each : description.getChildren()) { if (shouldRun(each)) { return true; } } return false; } private boolean hasCorrectCategoryAnnotation(Description description) { List> categories = categories(description); if (categories.isEmpty()) { return fIncluded == null; } for (Class each : categories) { if (fExcluded != null && fExcluded.isAssignableFrom(each)) { return false; } } for (Class each : categories) { if (fIncluded == null || fIncluded.isAssignableFrom(each)) { return true; } } return false; } private List> categories(Description description) { ArrayList> categories = new ArrayList>(); categories.addAll(Arrays.asList(directCategories(description))); categories.addAll(Arrays.asList(directCategories(parentDescription(description)))); return categories; } private Description parentDescription(Description description) { Class testClass = description.getTestClass(); if (testClass == null) { return null; } return Description.createSuiteDescription(testClass); } private Class[] directCategories(Description description) { if (description == null) { return new Class[0]; } Category annotation = description.getAnnotation(Category.class); if (annotation == null) { return new Class[0]; } return annotation.value(); } } public Categories(Class klass, RunnerBuilder builder) throws InitializationError { super(klass, builder); try { filter(new CategoryFilter(getIncludedCategory(klass), getExcludedCategory(klass))); } catch (NoTestsRemainException e) { throw new InitializationError(e); } assertNoCategorizedDescendentsOfUncategorizeableParents(getDescription()); } private Class getIncludedCategory(Class klass) { IncludeCategory annotation = klass.getAnnotation(IncludeCategory.class); return annotation == null ? null : annotation.value(); } private Class getExcludedCategory(Class klass) { ExcludeCategory annotation = klass.getAnnotation(ExcludeCategory.class); return annotation == null ? null : annotation.value(); } private void assertNoCategorizedDescendentsOfUncategorizeableParents(Description description) throws InitializationError { if (!canHaveCategorizedChildren(description)) { assertNoDescendantsHaveCategoryAnnotations(description); } for (Description each : description.getChildren()) { assertNoCategorizedDescendentsOfUncategorizeableParents(each); } } private void assertNoDescendantsHaveCategoryAnnotations(Description description) throws InitializationError { for (Description each : description.getChildren()) { if (each.getAnnotation(Category.class) != null) { throw new InitializationError("Category annotations on Parameterized classes are not supported on individual methods."); } assertNoDescendantsHaveCategoryAnnotations(each); } } // If children have names like [0], our current magical category code can't determine their // parentage. private static boolean canHaveCategorizedChildren(Description description) { for (Description each : description.getChildren()) { if (each.getTestClass() == null) { return false; } } return true; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy