JUnit4根据自定义java注释跳过测试

use*_*960 9 java junit annotations

我希望我的JUnit4测试可以根据我用Java创建的自定义注释来执行.此自定义注释的目的是让JUnit4注意,只有在机器的平台与注释中指定的平台匹配时才应运行测试.

说我有以下注释:

public @interface Annotations {
    String OS();
    ...
}
Run Code Online (Sandbox Code Playgroud)

以下测试:

public class myTests{

    @BeforeClass
    public setUp() { ... }

    @Annotations(OS="mac")
    @Test
    public myTest1() { ... }

    @Annotations(OS="windows")
    @Test
    public myTest2() { ... }

    @Annotation(OS="unix")
    @Test
    public myTest3() { ... }

}
Run Code Online (Sandbox Code Playgroud)

如果我要在Mac机器上执行这些测试,那么只应执行myTest1(),其余部分应该被忽略.但是,我目前仍然坚持我应该如何实现这一点.如何让JUnit读取我的自定义注释并检查是否应该运行测试.

Ale*_*exR 14

您可以使用类别,也可以实现自己的自定义JUnit运行程序.扩展默认的JUnit运行器非常简单,并允许您以您可能想要的任何方式定义要运行的测试列表.这包括仅查找具有特定注释的那些测试方法.我在下面包含代码示例,您可以将它们用作您自己实现的基础:

注解:

@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation {
   String OS();
}
Run Code Online (Sandbox Code Playgroud)

自定义亚军类:

public class MyCustomTestRunner extends BlockJUnit4ClassRunner {

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

   @Override
   protected List<FrameworkMethod> computeTestMethods() {
      // First, get the base list of tests
      final List<FrameworkMethod> allMethods = getTestClass()
            .getAnnotatedMethods(Test.class);
      if (allMethods == null || allMethods.size() == 0)
         return allMethods;

      // Filter the list down
      final List<FrameworkMethod> filteredMethods = new ArrayList<FrameworkMethod>(
            allMethods.size());
      for (final FrameworkMethod method : allMethods) {
         final MyCustomAnnotation customAnnotation = method
               .getAnnotation(MyCustomAnnotation.class);
         if (customAnnotation != null) {
            // Add to accepted test methods, if matching criteria met
            // For example `if(currentOs.equals(customAnnotation.OS()))`
            filteredMethods.add(method);
         } else {
            // If test method doesnt have the custom annotation, either add it to
            // the accepted methods, or not, depending on what the 'default' behavior
            // should be
            filteredMethods.add(method);
         }
      }

      return filteredMethods;
   }
}
Run Code Online (Sandbox Code Playgroud)

样品测试类:

@RunWith(MyCustomTestRunner.class)
public class MyCustomTest {
   public MyCustomTest() {
      super();
   }

   @Test
   @MyCustomAnnotation(OS = "Mac")
   public void testCustomViaAnnotation() {
      return;
   }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我发现完全具有此行为并将其作为报告中的跳过测试以提高意识的最佳方法是使用您自己的运行程序(如AlexR的回答),但是覆盖runChild方法,该方法允许选择测试但将其处理为忽略而不是完全排除。

要使用的注释

@Retention(RetentionPolicy.RUNTIME)
public @interface TargetOS {
    String family();

    String name() default "";

    String arch() default "";

    String version() default "";
}
Run Code Online (Sandbox Code Playgroud)

JUnit运行器

public class OSSensitiveRunner extends BlockJUnit4ClassRunner {
    public OSSensitiveRunner(Class<?> klass) throws InitializationError {
        super(klass);
    }

    @Override
    protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
        Description description = describeChild(method);
        if (method.getAnnotation(Ignore.class) != null) {
            notifier.fireTestIgnored(description);
        } else if (method.getAnnotation(TargetOS.class) != null) {
            final TargetOS tos = method.getAnnotation(TargetOS.class);
            String name = tos.name().equals("") ? null : tos.name();
            String arch = tos.arch().equals("") ? null : tos.arch();
            String version = tos.version().equals("") ? null : tos.version();
            if (OS.isOs(tos.family(), name, arch, version)) {
                runLeaf(methodBlock(method), description, notifier);
            } else {
                notifier.fireTestIgnored(description);
            }
        } else {
            runLeaf(methodBlock(method), description, notifier);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

测试中的用法

@RunWith(OSSensitiveRunner.class)
public class SeleniumDownloadHelperTest {
...
Run Code Online (Sandbox Code Playgroud)

并限制特定方法

@Test
@TargetOS(family = "windows")
public void testGetFileFromUrlInternetExplorer() throws Exception {
    ...
}
Run Code Online (Sandbox Code Playgroud)