Junit5快速上手指南

Junit5是Junit一個非常大的改進版本,根據Junit5官方文檔上的描述:

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

  • JUnit Platform:提供了在JVM上啓動測試框架的基礎,包括Junit核心的API等等。
  • JUnit Jupiter:提供了用於編寫測試代碼的新的編程和擴展模型。
  • JUnit Vintage:提供了使用JUnit3和4編寫測試方法的兼容。

相比於之前Junit4,個人感覺在使用上比較大的一個改進是在參數化測試這塊,本來很多的測試場景要寫的重複場景就比較多,通過參數化測試,可以大量減少測試的編寫。

比如用經典的FizzBuzz來進行練習.

@Data
public class FizzBuzz {

    public String say(int number) {

        if (isMultiple(number, 3) && isMultiple(number, 5)) {
            return "fizzbuzz";
        }

        if (isMultiple(number, 3)) {
            return "fizz";
        }

        if (isMultiple(number, 5)) {
            return "buzz";
        }

        return "hello";
    }

    private boolean isMultiple(int number, int i) {
        return number % i == 0;
    }

}

如果想寫一個測試來覆蓋所有的邏輯,按照原來Junit4的方法,要寫四個方法來覆蓋這些邏輯,但是再Junit5中可以用註解來解決這個問題。

public class Junit5Test {

    @DisplayName("FizzBuzz Practice")
    @ParameterizedTest(name = "number {0} say {1}")
    @CsvSource({
            " '1', 'hello' ",
            " '3', 'fizz' ",
            " '5', 'buzz' ",
            " '15', 'fizzbuzz' "
    })
    public void test(int number, String result) {

        FizzBuzz fizzBuzz = new FizzBuzz();

        String say = fizzBuzz.say(number);

        Assertions.assertEquals(result, say);

    }

}

通過@CsvSource註解(還有其他的XXXXSource註解)來進行參數化的測試,這個函數會根據參數進行多次執行,確保將代碼邏輯的分支都儘量覆蓋到。

好用的Junit插件和測試工具

這裏介紹幾個我平時會用到的Junit5擴展插件,在這些插件的加持下,測試代碼會寫的簡單很多。

  1. https://github.com/junit-pioneer/junit-pioneer
  2. https://github.com/joshka/junit-json-params
  3. https://github.com/j-easy/easy-random

第一個介紹的是junit-pioneer,在測試中經常會碰到使用一些對入參排列組合使用的情況,使用junit-pioneer這個插件,可以幫助我們比較輕鬆地應對這種情況。

public class CombinationTest {

    @CartesianProductTest
    @CartesianValueSource(strings = {"type1", "type2"})
    @CartesianValueSource(strings = {"action A", "action B"})
    public void combinationTest(String type, String action) {
        System.out.printf("%s --> %s \n", type, action);
    }

}

執行的效果:

type1 --> action A 
type1 --> action B 
type2 --> action A
type2 --> action B 

junit-pioneer包含了很多對Junit5的擴展,有興趣的話,可以在它的文檔中繼續探索他的一些功能:https://junit-pioneer.org/docs/

第二個插件是junit-json-params, 這個插件

public class JsonTest {
    @ParameterizedTest
    @JsonSource("[{\"key\":\"value1\"},{\"key\":\"value2\"}]")
    @DisplayName("provides an array of objects")
    void arrayOfObjects(JsonObject object) {
        Assertions.assertTrue(object.getString("key").startsWith("value"));
    }
}

第三個推薦的是一個對象生成器框架Easy Random,在編寫測試過程中,組裝對象通常是一個非常費勁的事情,很多參數也用不到,通過Easy Random可以快速組裝出一個隨機對象。

public class ObjectRandomTest {

    @Test
    public void test(){

        Book book = new EasyRandom().nextObject(Book.class);

        Assertions.assertNotNull(book.getBookName());
        Assertions.assertNotNull(book.getAuthor());

    }

    @Data
    static class Book {

        private String bookName;

        private String author;

    }

}

Maven中的POM

以下是剛剛提到的這些框架在Maven中的配置,另外重複的註解這種寫法(junit-pioneer用到了)只有Java8以及以上的版本才支持,所以maven中編譯的版本一定要在1.8以上。

<properties>
        <junit.jupiter.version>5.7.1</junit.jupiter.version>
        <junit.platform.version>1.7.1</junit.platform.version>
        <junit-pioneer.version>1.3.8</junit-pioneer.version>
        <junit-json-params.version>5.6.2-r0</junit-json-params.version>
        <javax.json.version>1.1.3</javax.json.version>
        <easy-random-core.version>4.3.0</easy-random-core.version>
        <lombok.version>1.18.20</lombok.version>
</properties>

<dependencies>
        <!--junit5-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.jupiter.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-runner</artifactId>
            <version>${junit.platform.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit-pioneer</groupId>
            <artifactId>junit-pioneer</artifactId>
            <version>${junit-pioneer.version}</version>
            <scope>test</scope>
        </dependency>
        <!--/junit5-->
        <!--json plugin dependency-->
        <dependency>
            <groupId>net.joshka</groupId>
            <artifactId>junit-json-params</artifactId>
            <version>${junit-json-params.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.json</groupId>
            <artifactId>javax.json-api</artifactId>
            <version>${javax.json.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.json</artifactId>
            <version>${javax.json.version}</version>
        </dependency>
        <!--/json plugin dependency-->
        <!--EasyRandom-->
        <dependency>
            <groupId>org.jeasy</groupId>
            <artifactId>easy-random-core</artifactId>
            <version>${easy-random-core.version}</version>
        </dependency>
        <!--/EasyRandom-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>provided</scope>
        </dependency>
</dependencies>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章