たとえばDBは本番環境ではOracle、テスト環境ではH2を使っているケースがあるとします。その場合、Oracleでは動くがH2では動かないSQLを作成してしまうことが考えられます。
他にも、本番環境はAmazon RDS for Oracleを使っているが、テスト環境で用意できているOracleのバージョンが合わないパターンもあるでしょう。バージョンによっては動かないSQLを作成してしまうことも考えられます(例:ALTER SEQUENCEはOracle 18cから使えるが、それ以前のバージョンはDROP/CREATEするしかない)。
この記事ではAssumeTrueを使用して、事前条件を満たせないテストがあった時に、テストを安全に終了させます。
ゴール
事前条件を満たしていないテストを終了させる。ただし、テスト終了後はDisabledのように、正常終了とも異常終了とも異なる状態にする。
環境
- Java
- 15
- org.springframework.boot
- 2.5.2
- JUnit
- 5.7.1
ユースケース
- 特定の環境でしか動かないテストを特定の環境だけで動くようにする
- OS
- DB
- 等々
対応
大きく2つ、AssumeTrue
とAssumingThat
のメソッドがあります。
AssumeTrue
AssumeTrue
では事前条件を満たせていない場合、以後の処理を停止させます。
使い方として、org.junit.jupiter.api.Assumptions#assumeTrue
の第1パラメータに事前条件を記載します。第2パラメータに失敗時のメッセージを記載します。
本来であればorg.junit.jupiter.api.Assertions.fail
で失敗しますが、AssumeTrue
以後の処理を停止させているために安全に終了します。
@Test void test_01() { assumeTrue(true); fail(); // 結果メッセージ // Assumption failed: assumption is not true } @Test void test_02() { assumeTrue(true, "このテストはoracle環境では動きません"); fail(); // 結果メッセージ // Assumption failed: このテストはoracle環境では動きません。 }
なお、AssumeFalse
も存在しますが、出力するメッセージが混乱してしまったので、私は推奨しません。
AssumingThat
AssumingThat
では事前条件を満たせていない場合でも、以後の処理を実行します。特定の環境のみ追加テストを行うイメージでよいでしょう。
使い方として、org.junit.jupiter.api.Assumptions#assumingThat
の第1パラメータに事前条件を記載します。第2パラメータに追加テストを記載します。
@Test void test_01() { assumingThat( true, () -> { // ここでエラーになったら処理終了する。 assertThat(1).isEqualTo(1); } ); // assumingThatはここも実行する // fail(); }
なお、機能として紹介はしますが個人的にはAssumingThat
は推奨しません。理由としては条件分岐が入ったことにより、テストが複雑になるからです。
備考
今回紹介したメソッドで事前条件に一致しない場合、TestAbortedException
を発生させます。JUnit 5単体で使用している場合は安全に処理はしてくれますが、メッセージを出力してくれません。
もし、メッセージを確認したい場合は、@SpringJUnitConfig
等のフレームワークのテストアノテーションを使いましょう。
# ログ抜粋 21:35:12.828 [Test worker] ... - After test method: context [DefaultTestContext@799f7b8a testClass = AssumeTests.AssumeTrue, testInstance = kirimaru.biz.domain.AssumeTests$AssumeTrue@1836d0cc, testMethod = test_02@AssumeTests.AssumeTrue, testException = org.opentest4j.TestAbortedException: Assumption failed: このテストはoracle環境では動きません ...
なお、@SpringBootTest
だとメッセージを出力してくれなかったので、あんまりメッセージを作りこんでも無意味かもしれません。AssumeTrue
で事前条件を満たさなかったときに、標準出力にメッセージを設定する方法がわからなかったので、教えていただけると助かります…。
ちなみに
そもそも、Springの機能にorg.springframework.test.context.junit.jupiter.DisabledIf
というもっと簡単に使えそうな機能がありました。
軽い気持ちで「Disabled」に「If」使えたら楽だなーって思っていたのが、そのままありました。
こちらはまったく検証していませんので、DisabledIf
も検証して、今後記事にする予定です。
終わりに
ピュアな機能として学ぶことも大事ですが、やはりライブラリは便利な機能を提供してますね。ライブラリの機能って本当に知らない機能は知らないから困る…。
ま、まぁ、こういうことができる、ということがわかっていれば他の言語でも同様の機能がありそうだ、というアタリをつけられるので、1つ成長したと思うことにします。
この記事お役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。
参考
- JUnit5 assumeメモ(Hishidama's JUnit5 Assumptions Memo)
- JUnit 5 User Guide
- Assumptions (JUnit 5.0.0 API)
- DisabledIf (Spring Framework 5.3.9 API) - Javadoc