うさぎ組

ソフトウェア開発、チームによる製品開発、アジャイル、ソフトウェアテスト

JUnit 4.12の新機能紹介まとめ

全国50万のJUnit4ユーザーさん。使っている言語とテスティングフレームワークののMLとGithubやBitBucketリポジトリを監視していると思うので今さらかもしれませんが、2014/7/30にJUnit4.12 Beta-1がリリースされました。

結構楽しい機能が追加されているので、見逃している方のために情報を共有させていただければと思います。

基本的にリリースから抜粋しながら紹介ですがご容赦ください。

Release Notes

junit/ReleaseNotes4.12.md at master · junit-team/junit · GitHub

全体の感想

JUnit4がおれの足元にやっと追いついたと思った。(今までJUnitとSpockを魔改造しまくってた。)

テストランナー系

クラス階層化

JUnit魔改造コミュニティに朗報です。私たちのテストランナーでよしなにやっておけば、inner classをネストさせることができるようになりました。今まではEnclosedでstatic classしかネストできませんでしたが。つまりこんな感じのコードが書けます。pull-req当人的にはcontext-nestできるぜー!って喜んでいましたが、個人的にはもっと他の使い方もできそうでうれしい。

@RunWith(KyonmmOriginalRunner)
class Sample {
    @Test
    public void topLevelTest(){
    }
    public class Child {
        @Test
        public void childTestMethod(){

        }

        public class GrandChild{
            @Test
            public void grandChildTestMethod(){

            }
        }
    }
}

個人的にはこれで十分ですが、他にも改善があります。

アノテーションヴァリデータのフレームワーク

JUnit魔改造コミュニティでは自分でアノテーションをつくっていきますが、特定Annotationではこれを満たしているべきとAnnotationValidatorをいい感じに呼び出すためにアノテーションが追加されました。@ValidateWithです。

// 利用するアノテーション

@Retention(RetentionPolicy.RUNTIME)
@Inherited
@ValidateWith(MyAnnotationValidator.class) // このアノテーションではこれを満たしているべき
public @interface MyAnnotation {
    Class<?>[] value();
}

// AnnotationValidatorを使ったヴァリデートの実装


public final class MyAnnotationValidator extends AnnotationValidator {

    @Override
    public List<Exception> validateAnnotatedMethod(FrameworkMethod method) {
      // なんか実装して、不正だったらエラーを返す
    }
}

テスト通知がスレッドセーフになった

テストを高速化しようとしたり、まぁ普通に並行とか分散処理していると、たまにテストの通知が変な状態になったりしているときがあったのですが、スレッドセーフになったようです。 まだ未検証ですが、期待しています。

Assert系

assertのオーバーロードが追加

Assert.assertNotEqualsにfloatを引数にとるものとboolean[]を引数にとるものが追加されました。まぁ必要なこともあるかもしれません。floatを使う場面は滅多にないかもしれませんが。

Rule系

例外補足できなかった時のメッセージを指定できるようになった

ExpectedExceptionを使って例外が投げられることのテストを記述できましたが、今回の対応で例外が投げられなかったときに表示するメッセージを指定できるようになりました。

class ExpectedExceptionMessageSample {
    @Rule
    public ExpectedException e = ExpectedException.none()
    @Test
    public void topLevelTest(){
        e.expect(IndexOutOfBoundsException)
        e.reportMissingExceptionWithMessage("見つからなかったー><。")
    }

}

Timeout指定に使うクラスのコンストラクタやファクトリーメソッドが増えた

あるテストメソッドがx秒以上実行していたら失敗するということもJUnitでは可能ですが、そのTimeoutの秒数を指定する方法が増えた感じです。

// ファクトリーメソッド版

@Rule public final TestRule timeoutFromFactory = Timeout.millis(30)

// コンストラクタ版
@Rule public final TestRule timeoutFromConstructor = new Timeout(30, TimeUnit.MILLISECONDS);

Debugモード時だけ特定Ruleをオフにすることできるようになった

例えば、Debugでテストを実行しているときにタイムアウトのRuleは効いてほしくないので次のようにすることで起動しないようにできます。

@Rule public DisableOnDebug t = new DisableOnDebug(Timeout.seconds(5));

CategoryとかDatapointとかTheoryとか拡張されていたけど、まったく興味ない。すまぬ。というか、たぶんみんなもたいして使っていないのでは。。。Spock使えし。。。(うそです。

まとめ

ということで、みんなでJUnit4.12-Beta-1のバグだしに貢献するために既存のOSSのビルドスクリプトをとにかく4.12-Beta-1にしてみてissueを投げつけて、pull-req投げつけましょう。

というか、普通に魔改造しやすくなっているし、使いやすくなっていてよいです。

JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)

JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)

実践テスト駆動開発 テストに導かれてオブジェクト指向ソフトウェアを育てる (Object Oriented SELECTION)

実践テスト駆動開発 テストに導かれてオブジェクト指向ソフトウェアを育てる (Object Oriented SELECTION)