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扩展插件,在这些插件的加持下,测试代码会写的简单很多。
- https://github.com/junit-pioneer/junit-pioneer
- https://github.com/joshka/junit-json-params
- 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以上。
5.7.1
1.7.1
1.3.8
5.6.2-r0
1.1.3
4.3.0
1.18.20
org.junit.jupiter
junit-jupiter-engine
${junit.jupiter.version}
test
org.junit.platform
junit-platform-runner
${junit.platform.version}
test
org.junit-pioneer
junit-pioneer
${junit-pioneer.version}
test
net.joshka
junit-json-params
${junit-json-params.version}
test
javax.json
javax.json-api
${javax.json.version}
org.glassfish
javax.json
${javax.json.version}
org.jeasy
easy-random-core
${easy-random-core.version}
org.projectlombok
lombok
${lombok.version}
provided