1

对于一组 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 { }
4

1 回答 1

1

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

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

否则computeTestMethods()inMyAnnotationRunner 将返回一个空列表。

此外,如果您还想运行任何带有注释的内容,则@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();
    }
}
于 2013-11-14T17:49:48.277 回答