为JUnit创建自己的@Test注释

时间:2013-11-14 15:29:04

标签: java unit-testing junit annotations junit4

对于一组JUnit 4.11测试,我创建了一个自己的注释(让我们称之为@MyTest),我将其应用于某些单元测试。就目前而言,我必须使用@Test@MyTest注释这些测试 - 这不是我认为的最佳解决方案。由于注释无法继承,我尝试构建自定义运行器,但到目前为止还没有成功。以下是目前的情况:

public class MyRunner extends Suite {

    public MyRunner(Class<?> klass, RunnerBuilder builder)
            throws InitializationError {
        super(klass, modifyBuilder(builder));
    }

    private static final RunnerBuilder modifyBuilder(RunnerBuilder builder) {
        if(AllDefaultPossibilitiesBuilder.class.isAssignableFrom(builder.getClass())) {    
            return new AllDefaultPossibilitiesBuilder(true) {
                @Override
                public Runner runnerForClass(Class<?> testClass)
                        throws Throwable {
                    List<RunnerBuilder> builders = Arrays.asList(
                            ignoredBuilder(),
                            annotatedBuilder(),
                            suiteMethodBuilder(),
                            junit3Builder(),
                            junit4Builder(),
                            myTestBuilder());

                    for (RunnerBuilder each : builders) {
                        Runner runner = each.safeRunnerForClass(testClass);
                        if (runner != null) {
                            return runner;
                        }
                    }
                    return null;
                }

                private RunnerBuilder myTestBuilder() {
                    return new RunnerBuilder() {

                        @Override
                        public MyAnnotationRunner runnerForClass(Class<?> testClass)
                                throws Throwable {
                            return new MyAnnotationRunner(testClass);
                        }
                    };
                }
            };
        } else {
            return builder;
        }
    }
}

MyAnnotationRunner类:

public class MyAnnotationRunner extends BlockJUnit4ClassRunner {

    public MyAnnotationRunner(Class<?> klass) throws InitializationError {
        super(klass);
    }

    @Override
    protected List<FrameworkMethod> computeTestMethods() {
        return getTestClass().getAnnotatedMethods(MyTest.class);
    }

    @Override
    protected void validateTestMethods(List<Throwable> errors) {
        validatePublicVoidNoArgMethods(MyTest.class, false, errors);
    }
}

但是到目前为止,当我运行测试时,它并不关心@MyTest注释;事实上,如果我在构建器列表中注释掉行junit4Builder(),,它根本不会运行任何测试。

我走错路还是这是正确的想法但到目前为止还不完整? (我无法切换到TestNG或其他测试框架,以防任何人想要建议。)

修改

解决方案(由Bobbo建议)不在上面发布的代码中 - 这似乎是正确的。但@MyTest注释缺少@Retention注释;正确的定义应如下所示:

@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest { }

1 个答案:

答案 0 :(得分:1)

确保使用保留注释将MyTest注释设置为在运行时保留,即

@Retention( RetentionPolicy.RUNTIME )
public @interface MyTest {}

否则computeTestMethods()中的MyAnnotationRunner将返回一个空列表。

此外,如果您还要运行使用@Test注释的任何内容,则需要将方法更改为以下内容:

protected List<FrameworkMethod> computeTestMethods() {
    List<FrameworkMethod> methods = new ArrayList<>(); 
    methods.addAll(getTestClass().getAnnotatedMethods(Test.class));
    methods.addAll(getTestClass().getAnnotatedMethods(MyTest.class));
    return methods;
}

我没有使用套件对此进行测试,但我只是使用跑步者运行测试类,它似乎可以按照您的要求运行:

@RunWith(MyAnnotationRunner.class)
public class Tests {
    @Test
    public void testUsingNormalTestAnnotation() {
        Assert.fail();
    }

    @MyTest
    public void testUsingMyTestAnnotation() {
        Assert.fail();
    }
}