JUnit5でネストしたテストと実行順序を指定する(@Nestedと@Order)

エキサイト株式会社メディア事業部の佐々木です。SpringBoot/Javaでメディア開発を行っていますが、単体テストでよく使用するJUnit5の@Nested@Orderの紹介です。

前提

環境は下記になります。

# Java
openjdk version "19.0.1" 2022-10-18
OpenJDK Runtime Environment Corretto-19.0.1.10.1 (build 19.0.1+10-FR)
OpenJDK 64-Bit Server VM Corretto-19.0.1.10.1 (build 19.0.1+10-FR, mixed mode, sharing)

# JUnit
org.junit.jupiter:junit-jupiter-api:5.8.1

build.gradle

plugins {
    id 'java'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    testImplementation(platform('org.junit:junit-bom:5.9.1'))
    testImplementation('org.junit.jupiter:junit-jupiter')
}

test {
    useJUnitPlatform()
}

@Nested

JUnit4の頃は、classのネスト等もできずにフラットに書いていましたが、JUnit5からはネストして書くことが可能です。

コード

JUnit5では、親テストクラスの中に子テストクラスを@Nestedで表現できます。

public class MainTest {

    @BeforeEach // 親クラスのsetup
    void setup() {
        System.out.println("main setup:");
    }

    @Nested
    class SecondTest {

        @BeforeEach // 子クラスのsetup
        void setup(){
            System.out.println("Second setup:");
        }

        @Test
        void test1(){
            System.out.println("Second test1:");
        }

        @Test
        void test2(){
            System.out.println("Second test2:");
        }
    }
}


実行結果:
===
main setup:
Second setup:
Second test1:
main setup:
Second setup:
Second test2:
===

実行すると子クラスのテストメソッドが実行される度にMainのsetup -> SecondTestのsetup -> SecondTestのtest1 が実行されます。

Order

Junit5では、テストの実行順は保証されません。テストは単体で行うのが通常なのですが、必要な場合は@Orderをつけて実行します。

Classの実行順を指定する場合

Classの場合はClassに@TestClassOrderをつけて、@Order(n)をつけます。@TestClassOrderがない場合は@Orderは無視されます。

@TestClassOrder(ClassOrderer.OrderAnnotation.class)
public class MainTest {

    @BeforeEach
    void setup() {
        System.out.println("main setup:");
    }

    @Nested
    @Order(1)
    class SecondTest {

        @BeforeEach
        void setup(){
            System.out.println("Second setup:");
        }

        @Test
        void test1(){
            System.out.println("Second test1:");
        }

        @Test
        void test2(){
            System.out.println("Second test2:");
        }
    }

    @Nested
    @Order(2)
    class ThirdTest {
        @BeforeEach
        void setup(){
            System.out.println("Third setup:");
        }

        @Test
        void test1(){
            System.out.println("Third test1:");
        }

        @Test
        void test2(){
            System.out.println("Third test2:");
        }
    }
}

実行結果:
==
main setup:
Second setup:
Second test1:
main setup:
Second setup:
Second test2:
main setup:
Third setup:
Third test1:
main setup:
Third setup:
Third test2:

==

指定した順序で実行されました。

メソッドの実行順を指定する場合

メソッドの順番を指定したいClassに@TestMethodOrderアノテーションを書き、@Order(n)を書きます。こちらも指定しないと@Orderを書いても無視されます。

@TestClassOrder(ClassOrderer.OrderAnnotation.class)
public class MainTest {

    @BeforeEach
    void setup() {
        System.out.println("main setup:");
    }

    @Nested
    @Order(1)
    @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
    class SecondTest {

        @BeforeEach
        void setup(){
            System.out.println("Second setup:");
        }

        @Test
        @Order(2)
        void test1(){
            System.out.println("Second test1:");
        }

        @Test
        @Order(1)
        void test2(){
            System.out.println("Second test2:");
        }
    }

    @Nested
    @Order(2)
    @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
    class ThirdTest {
        @BeforeEach
        void setup(){
            System.out.println("Third setup:");
        }

        @Test
        @Order(2)
        void test1(){
            System.out.println("Third test1:");
        }

        @Test
        @Order(1)
        void test2(){
            System.out.println("Third test2:");
        }
    }
}

実行結果:
===
main setup:
Second setup:
Second test2:
main setup:
Second setup:
Second test1:
main setup:
Third setup:
Third test2:
main setup:
Third setup:
Third test1:
===

メソッドでも指定した通り実行できました。

まとめ

JUnit5から追加された@Nested@Orderですが、結構便利に使えます。結構前にでているJUnit5ですが、他にも色々機能追加がされているので、引き続き紹介させていただきたいと思います。

最後に

エキサイトではフロントエンジニア、バックエンドエンジニア、アプリエンジニアを随時募集しております。長期インターンも歓迎していますので、興味があれば連絡いただければと思います。

カジュアル面談はこちらになります! meety.net

募集職種一覧はこちらになります!(カジュアルからもOK) www.wantedly.com