2012-11-27 10 views
9

Javaで作成したカスタムアノテーションに従ってJUnit4テストを実行したいと思います。このカスタムアノテーションの目的は、JUnit4が、マシンのプラットフォームがアノテーションで指定されたプラットフォームと一致する場合にのみ、テストを実行する必要があることに注意することです。実行する必要があります)私はmyTest1(そして、Macのマシンでこれらのテストを実行した場合JUnit4カスタムJavaアノテーションに従ったテストをスキップ

public class myTests{ 

    @BeforeClass 
    public setUp() { ... } 

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

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

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

} 

public @interface Annotations { 
    String OS(); 
    ... 
} 

そして、次のテスト:

は、私は以下の注釈を持っていると言います残りは無視する必要があります。しかし、私は現在、これをどのように実装すべきかについて固執しています。 JUnitにカスタムアノテーションを読み込ませ、テストを実行するかどうかをチェックする方法を教えてください。

+2

に関するより多くの情報がありますか? – assylias

答えて

11

カテゴリを使用することも、独自のカスタムJUnitランナーを実装することもできます。デフォルトのJUnitランナーを拡張するのは簡単で、テストのリストを任意の方法で実行するように定義することができます。これには、特定のアノテーションを持つテストメソッドのみを検索することも含まれます。私はあなたが独自の実装のための基礎として使用することができ、以下のコードサンプルを含めています:

注釈:

@Retention(RetentionPolicy.RUNTIME) 
public @interface MyCustomAnnotation { 
    String OS(); 
} 

カスタムランナークラス:

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; 
    } 
} 

サンプルテストクラス:

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

    @Test 
    @MyCustomAnnotation(OS = "Mac") 
    public void testCustomViaAnnotation() { 
     return; 
    } 
} 
+0

私はカスタムランナーと答えを投稿しようとしていましたが、あなたがそれを言及したのを見て、代わりに答えを広げてもいいのですか? – Perception

+0

@Perception:してください、私はこれについてさらに洞察したいと思います。 – user1754960

+0

@AlexR:あなたが 'categories'で何を意味しているのかよく分からない場合は、これについてもう少し詳しくお聞かせください。 申し訳ありませんが、まだJUnitとJavaの初心者です。先進的でありがとう! – user1754960

4

私はこの動作を正確にして、レポート内の認識をスキップしてテストしたときに見つけた最良の方法は、(AlexRの答えのような)独自のランナーを使用していますが、テストを選ぶrunChildメソッド無視のように扱われ、完全に除外されるわけではありません。

注釈は

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

    String name() default ""; 

    String arch() default ""; 

    String version() default ""; 
} 

を使用する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); 
     } 
    } 
} 

試験

@RunWith(OSSensitiveRunner.class) 
public class SeleniumDownloadHelperTest { 
... 

で使用し、特定の方法

@Test 
@TargetOS(family = "windows") 
public void testGetFileFromUrlInternetExplorer() throws Exception { 
    ... 
} 
を制限します10
1

私が今までに見つけた最良の選択肢は、JUnit Ruleです。すぐに使えるファイルを持つlink to GitHubがあります。

0

これはまさにJUnitのカテゴリ(short introduction参照)のためのものです。

適切なカテゴリ(@Categoryを使用)ですべてのテストをマークしたら、すべてのテストを実行するスイートを作成することはできますが、間違ったカテゴリのテストまたは正しいカテゴリを持つすべてのテストが実行されます。(@IncludeCategoryと@ExcludeCategoryを使用すると、それらを組み合わせて選択範囲を絞り込むことができます)

カテゴリは、スイート、テストクラス、さらにはテストメソッドレベルでも使用できます。ここで

あなたは[カテゴリー](https://github.com/KentBeck/junit/wiki/Categories)を使用することができませんでしたJUnit Categories

関連する問題