Excluding a non param test in parameterized test class

前端 未结 10 823
粉色の甜心
粉色の甜心 2020-12-02 19:32

Is there any annotation in JUnit to exclude a non param test in parameterized test class?

10条回答
  •  温柔的废话
    2020-12-02 20:36

    It appears that TestNG does not suffer from this problem. I'm not that desperate so I modified the builtin Parameterized class to support this feature. Just annotate applicable tests as @NonParameterized. Note that this class only works with its on annotations, i.e. check your imports.

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import java.lang.reflect.Modifier;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Iterator;
    import java.util.List;
    
    import org.junit.Test;
    import org.junit.runner.Runner;
    import org.junit.runner.notification.RunNotifier;
    import org.junit.runners.BlockJUnit4ClassRunner;
    import org.junit.runners.Suite;
    import org.junit.runners.model.FrameworkMethod;
    import org.junit.runners.model.InitializationError;
    import org.junit.runners.model.Statement;
    import org.junit.runners.model.TestClass;
    
    /**
     * 

    * The custom runner Parameterized implements parameterized tests. * When running a parameterized test class, instances are created for the * cross-product of the test methods and the test data elements. *

    * For example, to test a Fibonacci function, write: * *
     * @RunWith(Parameterized.class)
     * public class FibonacciTest {
     *     @Parameters
     *     public static List<Object[]> data() {
     *         return Arrays.asList(new Object[][] {
     *                 Fibonacci,
     *                 { {0, 0}, {1, 1}, {2, 1}, {3, 2}, {4, 3}, {5, 5},
     *                         {6, 8}}});
     *     }
     *
     *     private int fInput;
     *
     *     private int fExpected;
     *
     *     public FibonacciTest(int input, int expected) {
     *         fInput = input;
     *         fExpected = expected;
     *     }
     *
     *     @Test
     *     public void test() {
     *         assertEquals(fExpected, Fibonacci.compute(fInput));
     *     }
     * }
     * 
    *

    * Each instance of FibonacciTest will be constructed using the * two-argument constructor and the data values in the * @Parameters method. *

    */ public class Parameterized extends Suite { /** * Annotation for a method which provides parameters to be injected into the * test class constructor by Parameterized */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public static @interface Parameters { } /** * Annotation for a methods which should not be parameterized */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public static @interface NonParameterized { } private class TestClassRunnerForParameters extends BlockJUnit4ClassRunner { private final int fParameterSetNumber; private final List fParameterList; TestClassRunnerForParameters(Class type, List parameterList, int i) throws InitializationError { super(type); fParameterList = parameterList; fParameterSetNumber = i; } @Override public Object createTest() throws Exception { return getTestClass().getOnlyConstructor().newInstance( computeParams()); } private Object[] computeParams() throws Exception { try { return fParameterList.get(fParameterSetNumber); } catch (ClassCastException e) { throw new Exception(String.format( "%s.%s() must return a Collection of arrays.", getTestClass().getName(), getParametersMethod( getTestClass()).getName())); } } @Override protected String getName() { return String.format("[%s]", fParameterSetNumber); } @Override protected String testName(final FrameworkMethod method) { return String.format("%s[%s]", method.getName(), fParameterSetNumber); } @Override protected void validateConstructor(List errors) { validateOnlyOneConstructor(errors); } @Override protected Statement classBlock(RunNotifier notifier) { return childrenInvoker(notifier); } @Override protected List computeTestMethods() { List ret = super.computeTestMethods(); for (Iterator i = ret.iterator(); i.hasNext();) { FrameworkMethod frameworkMethod = (FrameworkMethod) i.next(); if (isParameterized() ^ !frameworkMethod.getMethod().isAnnotationPresent( NonParameterized.class)) { i.remove(); } } return ret; } protected boolean isParameterized() { return true; } } private class TestClassRunnerForNonParameterized extends TestClassRunnerForParameters { TestClassRunnerForNonParameterized(Class type, List parameterList, int i) throws InitializationError { super(type, parameterList, i); } protected boolean isParameterized() { return false; } } private final ArrayList runners = new ArrayList(); /** * Only called reflectively. Do not use programmatically. */ public Parameterized(Class klass) throws Throwable { super(klass, Collections. emptyList()); List parametersList = getParametersList(getTestClass()); if (parametersList.size() > 0) { try { runners.add(new TestClassRunnerForNonParameterized( getTestClass() .getJavaClass(), parametersList, 0)); } catch (Exception e) { System.out.println("No non-parameterized tests."); } } try { for (int i = 0; i < parametersList.size(); i++) { runners.add(new TestClassRunnerForParameters(getTestClass() .getJavaClass(), parametersList, i)); } } catch (Exception e) { System.out.println("No parameterized tests."); } } @Override protected List getChildren() { return runners; } @SuppressWarnings("unchecked") private List getParametersList(TestClass klass) throws Throwable { return (List) getParametersMethod(klass).invokeExplosively( null); } private FrameworkMethod getParametersMethod(TestClass testClass) throws Exception { List methods = testClass .getAnnotatedMethods(Parameters.class); for (FrameworkMethod each : methods) { int modifiers = each.getMethod().getModifiers(); if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)) return each; } throw new Exception("No public static parameters method on class " + testClass.getName()); } }

    Update: I'm trying to get this sort of thing added to junit.

提交回复
热议问题