概述
一、单元测试
单元测试就是模块测试,针对具体某块进行正确性的检验。在java这种,单元测试的最小单位是方法。单元测试属于白盒测试。
单元测试的优点:
1、提高软件的质量——能提前发现小模块里的问题,保障开发质量和程序的鲁棒性(面对发生很大的故障,程序还不至于崩溃);
2、减少重构时造成的影响——重构代码或者需求变动时,可能稍微改动了一点儿就引发一系列的bug,或者是改个小bug引发大bug。如果能做到单元测试,就可以让程序来检查是否有问题。
使用单元测试要注意的几个点:
1、要完全自动化,不要人为用System.out.println来打印日志看效果,要使用断言来验证;
2、测试用例之间不能相互调用;
3、测试用例能支持多次调用;
4、单元测试的粒度最好小一些,以免发生错误不好定位;
5、要符合BCDE(Border边界值弄特殊的值来测试,Correct正确的输入要得到正确的输出,Design和设计文档结合;Error测试的目的时发现程序有错误,要用非法操作、非法参数等)。
6、粗粒度的测试关注类覆盖率、方法覆盖率,只要有调用就算是覆盖到了;细粒度的测试关注行覆盖率;不能用覆盖率来考核,因为覆盖率高不代表单元测试设计得好。
二、JUnit5
Jupiter是JUnit5的核心(jupiter [ˈdʒuːpɪtə®] 木星)
引入jar包
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
与以前版本的JUnit不同,JUnit 5由三个不同子项目中的几个不同模块组成。
JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
JUnit Platform是基于JVM的运行测试的基础框架在,它定义了开发运行在这个测试框架上的TestEngine API。此外该平台提供了一个控制台启动器,可以从命令行启动平台,可以为Gradle和 Maven构建插件,同时提供基于JUnit4的Runner。
JUnit Jupiter是在JUnit 5中编写测试和扩展的新编程模型和扩展模型的组合.Jupiter子项目提供了一个TestEngine在平台上运行基于Jupiter的测试。
JUnit Vintage提供了一个TestEngine在平台上运行基于JUnit 3和JUnit 4的测试。
代码位置
测试类都要些在src/test/java下,不能写在业务代码文件夹中,这是为了保证代码结构规范。注意引入的是junit.jupiter的包,而不是junit的包(4及以下版本),否则一些方法会报错。
常用断言
在低版本的JUnit中,断言在Assert类中,而JUnit5的断言在Assertions类中。类中有多种静态方法,比如Assertions.assertTrue(),Asserions.assertEquals(),Assertions.assertNull(),Assertions.assertNotNull()等,这些方法都有不同重载的方法,参数不同。
public class TestNodeDemo {
private String id = "1000";
private String nodeTypeId = "6";
Node node = new Node(this.id,this.nodeTypeId);
@Test
public void testAssertEquals(){
nodeTypeId = "7";
assertEquals("你错了",nodeTypeId,node.printNodeTypeId());
}
@Test
public void testAssertTrue(){
assertTrue(1==2);
}
@Test
public void testAssetFalse(){
assertFalse(1==2);
}
@Test
public void testAssertSame(){
String a = "hi";
String b = "hi33";
assertSame(a,b);
}
@Test
public void testAssertNotNull(){
Object object = null;
assertNotNull(object);
}
@Test
public void testAssertNotNull2(){
Object object = null;
assertNotNull("你给我的东西是空的",object);
}
}
三、JUnit5新特性总结
新特性一、@Test注解标记在方法上,JUnit5不需要让方法标记为public
构建工具和IDE也能识别方法。例如上方代码,若用的junit的包,去掉方法上的public,会报错。
新特性二、初始化与销毁的注解变化
在JUnit5中,@Before注解换成了@BeforeEach,@After注解换成了@AfterEach;
@BeforeClass换成了@BeforeAll,@AfterClass换成了@AfterAll。
@BeforeAll——只执行一次,方法必须是静态的,因为执行这个时,还没有任何测试实例
@BeforeEach——每个测试执行前都会执行,方法必须是非静态的
@AfterAll——只执行一次,方法必须是静态的,因为执行这个时,还没有任何测试实例
@AfterEach——每个测试执行后都会执行,方法必须是非静态的
在一个类里执行有@Test注解的方法,且@Test是来自jupiter包,每个注解的加载顺序是:@BeforeAll,@BeforeEach,测试方法,@AfterEach,@AfterAll。带@Before、@After注解的这种junit4里的方法不会执行。
新特性三、使用@Nested 注解进行嵌套测试
使用任意嵌套的内部类作为单个测试类中附加的测试组成单元,可以一次性测试多个方法。
package demo;
import org.junit.jupiter.api.*;
public class TestNestedDemo {
//在所有的测试方法运行前执行
@BeforeAll
public static void testBeforeAll(){
System.out.println("哈哈,我是beforeAll方法");
}
//在每个测试方法运行前执行
@BeforeEach
public void testBeforeEach(){
System.out.println("当当,我是beforeEach方法");
}
@Nested
@DisplayName("@Nested注解,测试多个方法")
class NestedDemo {
@Test
public void testAnnotaion2() {
Assertions.assertTrue(3 == 1 + 1);
}
@Test
public void testAnnotaion3() {
Assertions.assertEquals("西施","东施","你是假的呀");
}
}
}
在日志中的打印是这样的:1、哈哈,我是beforeAll方法;2、当当,我是beforeEach方法;3、testAnnotaion2怎么错了;4、当当,我是beforeEach方法、5、你是假的呀 ==> testAnnotaion3怎么错了。
新特性四、@Disabled注解进行失效校验
@Disabled注解相当于junit包里的@Ignore注解。
@Test
@DisabledOnOs(OS.WINDOWS)
public void testAnnotaion2() {
Assertions.assertTrue(3 == 1 + 1);
}
在windows操作系统中,上述方法不会执行。
新特性五、@TestMethodOrder注解定义执行顺序
和@order注解结合使用,@Order是大于0的正整数,数字越小优先级越高。这样也能够实现多个方法一起测试哦!
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class JUnit5Demo {
@Test
@Order(2)
public void btestAdd1(){
Assertions.assertEquals(3,1+1);
}
@Test
@Order(1)
public void atestAdd2(){
Assertions.assertEquals(4,2+1);
}
}
上述代码会先执行方法2再执行方法1,如果去掉@Order注解,也会先执行方法2再执行方法1,因为默认加上的是@TestMethodOrder(MethodOrderer.Alphanumeric.class)注解,会按照方法名的字母来排序。
本文主要参考文章一
文章二
后记-学以致用
例一
想测试一个题为“给定一个含有n个正整数的数组和一个正整数s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度”的方法,以前都是些main方法,这次用JUnit5来测试一下:
已知输入:s = 7, nums = [2,3,1,2,4,3],输出:2
package demo;
import com.leetcode.D0127p3;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class D0127p3Test {
private static D0127p3 d0127p3;
@BeforeAll
static void initD0127p3(){
d0127p3 = new D0127p3();
}
@Test
void checkResult(){
int s = 7;
int[] nums = {2,3,1,2,4,3};
Assertions.assertEquals(2,d0127p3.minSubArrayLenM1(s,nums));
}
}
运行后没有报错,说明代码写得没问题。
例二
想多用几种参数试试,用@Nested注解,注意这个注解的包很容易引错,可以删掉重新引入。
package demo;
import com.leetcode.D0127p3;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
public class D0127p3Test {
private static D0127p3 d0127p3;
@BeforeAll
static void initD0127p3(){
d0127p3 = new D0127p3();
}
@Nested
class testMethods{
@Test
void checkResult(){
int s = 7;
int[] nums = {2,3,1,2,4,3};
Assertions.assertEquals(2,d0127p3.minSubArrayLenM1(s,nums));
}
@Test
void checkResult2(){
int s = 9;
int[] nums = {3,3,1,2,4,3};
Assertions.assertEquals(3,d0127p3.minSubArrayLenM1(s,nums));
}
}
}
两个方法都执行正确。
最后
以上就是平淡猫咪为你收集整理的JUnit5进行单元测试及JUnit5的新特性一、单元测试二、JUnit5三、JUnit5新特性总结后记-学以致用例二的全部内容,希望文章能够帮你解决JUnit5进行单元测试及JUnit5的新特性一、单元测试二、JUnit5三、JUnit5新特性总结后记-学以致用例二所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复