2015年8月2日日曜日

JUnitのRunner (Enclosed, Theories, Categories) を併用したときの動き

JUnit4の次のRunnerの関係を整理してみた。なお、JUnitのバージョンは4.12。
  • Enclosed
  • Theories
  • Categories

論理的にテストクラスを分類しつつ、並列化するための分類もしたくなることがあるので、JUnitの仕組みでどこまでできるか知っておきたくて。

では、早速。

EnclosedとTheoriesは併用できる。外部クラスEnclosingTheoryをJUnit実行すれば、内部クラスEnclosedTheoryがJUnit実行される。これでTheoriesを使いたいけれど、テストクラスを分けたくない場合は大丈夫。
@RunWith(Enclosed.class)
public class EnclosingTheory {
    @RunWith(Theories.class)
    public static class EnclosedTheory {
        @Theory
        public void testTheory(Fixture f) throws Exception {
            // test method.
        }
    }
}

EnclosedとCategoriesは併用できない。外部クラスEnclosingTheoryにカテゴリOuterを付けて、Categoriesを使ったテストスイートを実行しても、テストが見つからない。
@RunWith(Enclosed.class)
@Category(Outer.class)
public class EnclosingTheory {
    @RunWith(Theories.class)
    public static class EnclosedTheory {
        @Theory
        public void testTheory(Fixture f) throws Exception {
            // test method.
        }
    }
}
@RunWith(Categories.class)
@IncludeCategory(Outer.class)
@SuiteClasses(EnclosingTheory.class)
public class CategorizedTestSuite {
    // NoTestsRemainException is thrown.
}

ただ、内部クラスEnclosedTheoryを直接指定すれば、実行させられる。Enclosedの甲斐がないと見るか、互いに独立した分類が使えると見るか、悩ましい。
@RunWith(Enclosed.class)
public class EnclosingTheory {
    @RunWith(Theories.class)
    @Category(Inner.class)
    public static class EnclosedTheory {
        @Theory
        public void testTheory(Fixture f) throws Exception {
            // test method.
        }
    }
}
@RunWith(Categories.class)
@IncludeCategory(Inner.class)
@SuiteClasses(EnclosedTheory.class)
public class CategorizedTestSuite {
    // run testTheory.
}

上記でテストが実行されるので、CategoriesとTheoriesは併用できることが分かる。

調べて見ると、CategoriesとEnclosedはそれぞれSuiteのサブクラスだった。併用できないのもさもありなん。

以下は、調べながら考えたことをつらつらと。

こうして調べて見ると、Categoryアノテーションで並列化のための分類をするのは筋が悪い気がしてきた。MECEに分割したいのだけれど、アノテーションの付け忘れやテストスイートへの追加忘れがありそう。何並列にするかによるけれど、上位のパッケージ構成でざっくり割っちゃった方が安全かなぁ。

CIとの相性も考える必要がある。AntのJUnitタスクから実行するなら、パッケージ構成やファイル命名規約に加えてFileSetで色々できる(開発端末上では使えないけれど)。一方、MavenはCategoryにも対応している。そろそろAntから卒業した方がいい気がしてきた……。

なお、調べるために書いたコードはso-c/junit4.12-categories-configuration-sampleにアップしてある。ここに書いたスニペットよりゴチャゴチャしているけれど、ちゃんと動くのでこれはこれで。

1 件のコメント:

  1. こんにちは。

    実際にやってみると色々分かりますよね!

    返信削除