前言:
JUnit5比4增加了很多新特性,最近刚使用了一下JUnit5记录一下看到和使用了的新特性,
先看下JUnit5的的包结构
JUnit5的包结构:
JUnit5和4开始支持的java版本也不一样,JUnit4需要Java 5或更高版本,JUnit 5需要Java 8或更高版本。
新特性:
1.断言
在Junit4中,org.junit.Assert具有所有断言方法来验证预期结果和结果。
例如:
public static void assertEquals(long expected, long actual)
JUnit5断言使用的是org.junit.jupiter.api.assertions不再是assert。
例如:
public static void assertEquals(short expected, short actual)
2.常用注解
JUnit4 | JUnit5 | 说明 | |
---|---|---|---|
@Test | @Test | 表示该方法是一个测试方法。JUnit5与JUnit 4的@Test注解不同的是,它没有声明任何属性,因为JUnit Jupiter中的测试扩展是基于它们自己的专用注解来完成的。这样的方法会被继承,除非它们被覆盖 | |
@BeforeClass | @BeforeAll | 表示使用了该注解的方法应该在当前类中所有使用了@Test @RepeatedTest、@ParameterizedTest或者@TestFactory注解的方法之前 执行; | |
@AfterClass | @AfterAll | 表示使用了该注解的方法应该在当前类中所有使用了@Test、@RepeatedTest、@ParameterizedTest或者@TestFactory注解的方法之后执行; | |
@Before | @BeforeEach | 表示使用了该注解的方法应该在当前类中每一个使用了@Test、@RepeatedTest、@ParameterizedTest或者@TestFactory注解的方法之前 执行 | |
@After | @AfterEach | 表示使用了该注解的方法应该在当前类中每一个使用了@Test、@RepeatedTest、@ParameterizedTest或者@TestFactory注解的方法之后 执行 | |
@Ignore | @Disabled | 用于禁用一个测试类或测试方法 | |
@Category | @Tag | 用于声明过滤测试的tags,该注解可以用在方法或类上;类似于TesgNG的测试组或JUnit 4的分类。 | |
@Parameters | @ParameterizedTest 表示该方法是一个参数化测试 | ||
@RunWith | @ExtendWith | @Runwith就是放在测试类名之前,用来确定这个类怎么运行的 | |
@Rule | @ExtendWith | Rule是一组实现了TestRule接口的共享类,提供了验证、监视TestCase和外部资源管理等能力 | |
@ClassRule | @ExtendWith @ClassRule用于测试类中的静态变量,必须是TestRule接口的实例,且访问修饰符必须为public。 |
3.嵌套测试:
在测试用例比较多的情况下,JUnit5支持将测试用例嵌套,如下面的例子:
用DisplayName来标识测试用例,分层来显示
@DisplayName("A stack")
class TestingAStackDemo {
Stack<Object> stack;
@Test
@DisplayName("is instantiated with new Stack()")
void isInstantiatedWithNew() {
new Stack<>();
}
@Nested
@DisplayName("when new")
class WhenNew {
@BeforeEach
void createNewStack() {
stack = new Stack<>();
}
@Test
@DisplayName("is empty")
void isEmpty() {
assertTrue(stack.isEmpty());
}
@Test
@DisplayName("throws EmptyStackException when popped")
void throwsExceptionWhenPopped() {
assertThrows(EmptyStackException.class, () -> stack.pop());
}
@Test
@DisplayName("throws EmptyStackException when peeked")
void throwsExceptionWhenPeeked() {
assertThrows(EmptyStackException.class, () -> stack.peek());
}
@Nested
@DisplayName("after pushing an element")
class AfterPushing {
String anElement = "an element";
@BeforeEach
void pushAnElement() {
stack.push(anElement);
}
@Test
@DisplayName("it is no longer empty")
void isNotEmpty() {
assertFalse(stack.isEmpty());
}
@Test
@DisplayName("returns the element when popped and is empty")
void returnElementWhenPopped() {
assertEquals(anElement, stack.pop());
assertTrue(stack.isEmpty());
}
@Test
@DisplayName("returns the element when peeked but remains not empty")
void returnElementWhenPeeked() {
assertEquals(anElement, stack.peek());
assertFalse(stack.isEmpty());
}
}
}
}
4.顺序测试
在JUnit4中@FixMethodOrder注解来决定单测的执行顺序,但是这个很不方便,只能根据JVM或者名字排名来确定执行顺序。
在JUnit5中引入了@TestMethodOrder方法,配合@Order注解就可以按照自己指定的顺序来进行单元测试。
例如:
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class OrderTest {
@Test
@Order(2)
@Disabled
public void testTwo() {
System.out.println("执行单测2");
assertEquals(1, 1);
}
@Test
@Order(1)
public void testOne() {
System.out.println("执行单测1");
assertEquals(1, 1);
}
@Test
@Order(3)
public void testThree() {
System.out.println("执行单测3");
assertEquals(1, 1);
}
}
如上文的的输出就会是:
执行单元测试1
执行单元测试2
执行单元测试3
Order中可以填写的数字是非负数,数字越大,越后执行。