开发的测试必备- Junit5和mock&&postman和jmeter

一.前言知识

idea的单元测试插件-Squaretest :自动生成Mock单元测试

Squaretest 自动生成Mock单元测试

11

22

33

44

55

三-Junit5常用注解–大部分标记的是类

Junit5安装和运行

一.添加Junit5依赖

Spring Boot 2.2.0 版本开始引入 JUnit 5 作为单元测试默认库;在 Spring Boot 2.2.0 版本之前,spring-boot-starter-test 包含了 JUnit 4 的依赖;

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
</dependency>

二.如何启用运行测试案例

方式一:执行项目路径下的所有测试用例
mvn test
方式二:采用maven的窗口

三.idea本身三种方式如何快速生成"目标类的各个方法"的测试方法–>本质上这三个都是一样的

方式一:右键类名(或目标方法名)–>Go to–>Test

在这里插入图片描述

方式二:鼠标停留在类名(或目标方法名)上–>快捷键Alt+Enter:生成"Control或者Service的测试类"

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

方式三:鼠标停留在类名(或目标方法名)上–>快捷键Alt+Insert

在这里插入图片描述

在这里插入图片描述

四.借助idea插件Squaretest :自动生成Mock单元测试

Squaretest 自动生成Mock单元测试

五.Idea自带覆盖率扫描工具的使用

六.jacoco插件覆盖率扫描工具的使用。

第一套:常规注解

@Test:表明一个测试方法

@Disabled:禁用测试类或者方法

@DisplayName:测试类或者方法的显示名称

@Tag—>对测试用例进行分组

在这里插入图片描述

@RepeatedTest:此目标方法额外重复执行

在这里插入图片描述

  • 如图1.1标注,@DisplayName 可以定义显示类的名称,如图1.2标注,@DisplayName 可以定义显示方法的名称
  • 如图2的标注,@Disabled ,该方法不执行,会看到方法名称前面有一个禁用的小图标
  • 如图3的标注,@RepeatedTest 设置为2,看到该方法再执行了一次之后,又额外重复执行了2遍,所以该方法总共执行了3次

第二套:之前和之后

2.2、@BeforeAll

表明在所有测试方法执行之前执行的方法,且只执行一次

2.3、@AfterAll

表明在所有测试方法执行之后执行的方法,且只执行一次

2.4、@BeforeEach

表明在每个测试方法执行之前都会执行的方法

2.5、@AfterEach

表明在每个测试方法执行之后都会执行的风发

第三套:控制那些 狗xxText.java需要运行,进行跑测试案例

通过select来创建套件,通过包、类、和方法三个维度来选择需要执行的测试用例。所有条件是且的关系,求的是交集

使用classname进行匹配时,需要加上所在的包名(唉~ 好麻烦)

在这里插入图片描述

若交集为空,如下图效果:

在这里插入图片描述

若交集不为空,则执行匹配的用例:

在这里插入图片描述

使用口诀:通过select来创建套件,通过包、类、和方法三个维度来选择需要执行的测试用例

1.@RunWith(JUnitPlatform.class) -->执行套件

新建一个类TestRunWithDemo.java--.>作用就是制定哪些测试类,哪些测试方法运行跑测试案例
在这里插入图片描述

2.先创建"测试套件"的两个注解–>作用是扫描哪些测试类可以作为"测试套件"

@SelectPackage({“com.packageA”,“com.packageB”}) -->根据包-创建套件
@SelectClasses( {a.class,b.class,c.class} ) --.根据类-创建套件

3.过滤哪些测试包??

@IncludePackage(“包名”) -->在套件中,>过滤在所有的套件,获得需要执行的测试包
@ExcludePackages(“包名”) 在套件中,过滤剔除不需要执行的测试包

4.过滤哪些测试类??,即提前讲好哪些类不跑测试

@IncludeClassNamePatterns(“类名”) —>过滤在所有的套件,获得需要执行的测试类
@ExcludeClassNamePatterns(“类名”) —>在套件中,过滤剔除不需要执行的测试类

5.在套件中,过滤需要执行的测试方法

@IncludeTags(“tag”) -->在套件中,过滤在所有的套件,获得需要执行的测试方法
@ExcludeTags(“tag”) -->在套件中,过滤剔除不需要执行的测试方法

第五套:参数化–>主要是 @MethodSource 和@valueSource

注解 说明
|- @valueSource -| 通过注解可以直接指定携带的运行参数 |
| @EnumSource | 枚举参数元,允许我们通过将参数值有给定的Enum枚举类型传 |
| @MethodSource | 通过其他的Java方法函数来作为参数源 |
| @ArgumentSource | 参数类参数源,应用类必须实现ArgumentsProvide接口 |
| @CSVSource | csv格式作为参数源 |
| @CSVFileSource | csv文件作为参数源 |

在这里插入图片描述

以上是Junit5的参数化方式,在这里我就不一一介绍了,本人用的更多的MethodSource+yaml的参数化方式;因为yaml文档能够比较清晰地定义各种类型的参数,结合MethodSource注解就能够很方便的构建出不同类型的参数
简单的MethodSource实例

    // 添加成员@ParameterizedTest
    @MethodSource("testData")
    public void successTest(String name,String phone)  {
        System.out.println("name: " + name +"phone: " + phone)
    }
    // 返回用例数据
    public static Stream<Arguments> testData() {
	    return Stream.of(
		    Arguments.arguments("周杰伦","12121221211"),
		    Arguments.arguments("林俊杰","12121221212"),
		    Arguments.arguments("王力宏","12121221213"));
    }

第四套:结果–>断言匹配

在这里插入图片描述
上面试Junit5自带的断言方式,如果需要更复杂的断言可以使用hamcrest断言方式;
软断言:如果一个用例需要进行多次断言,就需要用到assertAll(需要先设置java8语法),使用软断言后不会因为一个断言的失败报错而中断测试
软断言实例:

@Test
void addTest(){  
    assertAll(
        ()->assertEquals(9==9),           
        ()->assertEquals(7==2),           
        ()->assertEquals(10==10)    
        );
 }
// 二:现将assert可执行语句进行储存,再用assertAll进行断言
ArrayList<Executable> assertList = new ArrayList<>();
for(int i = 0;i<3;i++){
    int result = 1 + i;
	assertList.add({
		// 先将断言语句存起来
    	() -> assertEquals(3,result);
    })
}
assertAll(assertList.Stream());

第六套:超时&&执行顺序&&重复

@Timeout(5)注解配置超时时间

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import static java.lang.Thread.sleep;
class TimeoutExampleTest {
    @Test
    @Timeout(7)
    void timeoutDemo1() throws InterruptedException {
        sleep(10000);
        System.out.println("超时用例1");
    }
    @Test
    void timeoutDemo2(){
        System.out.println("超时用例2");
    }
}
时间单位配置

在这里插入图片描述

可以结合注解@BeforeEach与@AfterEach

 import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import static java.lang.Thread.sleep;

class TimeoutExampleTest {
    @AfterEach
    @Timeout(3)
    void teardown() throws InterruptedException {
        sleep(40000);
        System.out.println("结束测试");
    }
    @BeforeEach
    @Timeout(3)
    void setup() throws InterruptedException {
        sleep(40000);
        System.out.println("开始测试");
    }
    @Test
    void timeoutDemo2(){
        System.out.println("超时用例2");
    }
}

@RepeatedTest:此目标方法额外重复执行

在这里插入图片描述

  • 如图1.1标注,@DisplayName 可以定义显示类的名称,如图1.2标注,@DisplayName 可以定义显示方法的名称
  • 如图2的标注,@Disabled ,该方法不执行,会看到方法名称前面有一个禁用的小图标
  • 如图3的标注,@RepeatedTest 设置为2,看到该方法再执行了一次之后,又额外重复执行了2遍,所以该方法总共执行了3次

@Order()指定测试方法的执行顺序

使用场景–.集成测试(主流程测试)

测试用例有业务逻辑相关
集成测试(主流程测试)

方法排序

在这里插入图片描述
类型 说明

OrderAnnotation(重点) @Order 注解指定排序
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
//设定排序方法为注解指定排序
@TestMethodOrder(OrderAnnotation.class)
class OrderedTestsDemo {
    @Test
    @Order(1)
    void nullValues() {
    }
    @Test
    @Order(2)
    void emptyValues() {
    }
    @Test
    @Order(3)
    void validValues() {
    }
}
DisplayName 根据显示名称排序
package com.hogwarts.JUnit5;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
//根据DisplayName进行排序
@TestMethodOrder(MethodOrderer.DisplayName.class)
class orderExampleTest {
    @Test
    @DisplayName("a用例")
    void firstCase() {
        System.out.println("第一条用例");
    }
    @Test
    @DisplayName("b用例")
    void secondCase() {
        System.out.println("第二条用例");
    }
    @Test
    @DisplayName("c用例")
    void thirdCase() {
        System.out.println("第三条用例");
        }
}
MethodName 根据方法名称排序
package com.hogwarts.JUnit5;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
// 设置排序类型为方法排序
@TestMethodOrder(MethodOrderer.MethodName.class)
class orderExampleTest {
    @Test
    void bCase() {
        System.out.println("第二条用例");
    }
    @Test
    void aCase() {
        System.out.println("第一条用例");
    }
    @Test
    void cCase() {
        System.out.println("第三条用例");
        }
}
Random 随机排序
package com.hogwarts.JUnit5;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
//设计排序类型为随机排序
@TestMethodOrder(MethodOrderer.Random.class)
class orderExampleTest {
    @Test
    void firstCase() {
        System.out.println("第一条用例");
    }
    @Test
    void secondCase() {
        System.out.println("第二条用例");
    }
    @Test
    void thirdCase() {
        System.out.println("第三条用例");
        }
}
类排序
类排序-DisplayName名称排序

在这里插入图片描述

package com.hogwarts.JUnit5;
import org.junit.jupiter.api.*;
// 指定类执行顺序的方式,DisplayName表示通过DisplayName排序
@TestClassOrder(ClassOrderer.DisplayName.class)
class orderExampleTest {
// 因为是多类执行,所以需要结合@Nested注解
    @Nested
    @DisplayName("b")
    class PrimaryTests {
        @Test
        void test1() {
            System.out.println("第一条用例");
        }
    }
    @Nested
    @DisplayName("a")
    class SecondaryTests {
        @Test
        void test2() {
            System.out.println("第二条用例");
        }
    }
}
类排序-Order 注解指定排序
import org.junit.jupiter.api.ClassOrderer;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestClassOrder;
// 指定类执行顺序的方式,OrderAnnotation表示通过order注解排序
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
class OrderedNestedTestClassesDemo {
    @Nested
    @Order(1)
    class PrimaryTests {
        @Test
        void test1() {
        }
    }
    @Nested
    @Order(2)
    class SecondaryTests {

        @Test
        void test2() {
        }
    }
}
类排序-根据类名排序
package com.hogwarts.JUnit5;
import org.junit.jupiter.api.*;

// 指定类执行顺序的方式,ClassName代表指定为类名排序
@TestClassOrder(ClassOrderer.ClassName.class)
class orderExampleTest {
// 因为是多类执行,所以需要结合@Nested注解
    @Nested
    class PrimaryTests {
        @Test
        void test1() {
            System.out.println("第一条用例");
        }
    }
    @Nested
    class SecondaryTests {
        @Test
        void test2() {
            System.out.println("第二条用例");
        }
    }
    @Nested
    class ThirdTests {
        @Test
        void test2() {
            System.out.println("第三条用例");
        }
    }
}
使用默认配置指定顺序

在这里插入图片描述

配置默认方法的执行顺序
#默认排序方式为随机排序
junit.jupiter.testmethod.order.default = org.junit.jupiter.api.MethodOrderer$Random
#默认排序方式为通过方法名排序
junit.jupiter.testmethod.order.default = org.junit.jupiter.api.MethodOrderer$MethodName
#默认排序方式为通过Order注解指定
junit.jupiter.testmethod.order.default = org.junit.jupiter.api.MethodOrderer$OrderAnnotation
#默认排序方式为通过DisplayName排序
junit.jupiter.testmethod.order.default = org.junit.jupiter.api.MethodOrderer$DisplayName
配置默认类的执行顺序
#默认排序方式为随机排序
junit.jupiter.testclass.order.default = org.junit.jupiter.api.ClassOrderer$Random
#默认排序方式为通过类名排序
junit.jupiter.testclass.order.default = org.junit.jupiter.api.ClassOrderer$ClassName
#默认排序方式为通过DisplayName排序
junit.jupiter.testclass.order.default = org.junit.jupiter.api.ClassOrderer$DisplayName
#默认排序方式为通过Order注解指定
junit.jupiter.testclass.order.default = org.junit.jupiter.api.ClassOrderer$OrderAnnotation

四.Mockito

参考文章一

参考文章二

参考文章三

参考文章四

参考文章五

引入依赖

<dependencies>
        <!--导入Mockito单元测试依赖-->
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <version>1.9.5</version>
            <scope>test</scope>
        </dependency>

        <!--导入junit单元测试依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

五.高并发测压工具postman 和 jmeter的玩法

必须学的发送请求的三大工具:postman ,jmeter,curl命令

万神技之必备工具:postman模拟并发密集访问testB

1.postman里新建多线程集合组
在这里插入图片描述
2.将"目标访问地址"添加进新新线程组
在这里插入图片描述

3.Run运行Collection
在这里插入图片描述

大批量线程高并发访问B,导致A失效了

万神技之必备工具jmeter模拟并发密集访问testB

在这里插入图片描述

六.实战之快速进行SpringBoot项目进行单元测试

方式二:使用IDEA的自带的测试小图标参考视频一

简述使用

在这里插入图片描述

方式一:SpringBoot整合Junit进行单元测试:参考文章一 参考文章二 参考文章三 参考视频

1.创建test测试文件夹

在这里插入图片描述

2. 添加Junit的起步依赖
<dependency> 
  <groupId>org.springframework.boot</groupId> 
  <artifactId>spring-boot-starter-test</artifactId> 
  <scope>test</scope> 
</dependency>
3.更快速的使用生成测试类
方式一:"Junit插件"生成测试类
方式二:快捷键Alt+Enter:生成"Control或者Service的测试类"

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

4.编写测试类三个常用注解
基于Service层的测试
实战小例子
//"其中,SpringRunner继承自SpringJUnit4ClassRunner,使用哪一个Spring提供的测试测试引擎都可以"-->作用就是告示当前测试类我所使用的测试工具是谁?是"SpringRunner"
@RunWith(SpringRunner.class) 

//"@SpringBootTest的属性指定的是引导类的字节码对象"-->用于启指向"主启动类"是谁,帮助你启动项目
@SpringBootTest(classes = MySpringBootApplication.class) 

public class MapperTest { 
    @Autowired 
    private UserMapper userMapper; 

     @Resource
    private UserService userService; 
    @Test   public void test() { 
        List<User> users = userMapper.queryUserList(); 
        System.out.println(users); 
    } 
}
基于Control层的测试:采用一个MockMVC对象来实现
@SpringBootTest
class Test {
    @Autowired 
    private WebApplicationContext webApplicationContext;
    //mvc 环境对象
    private MockMvc mockMvc;

    @BeforeEach
    public void init() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }    @Test
    void getXhCreateTaskRecord() throws Exception {
//        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
        final String json = "{}";
        final MockHttpServletRequestBuilder request = MockMvcRequestBuilders.post("/getXhCreateTaskRecord")
                .accept(MediaType.APPLICATION_JSON)
                .contentType(MediaType.APPLICATION_JSON_VALUE)
                //传json参数
                .content(json);
        final String contentAsString = mockMvc.perform(request).andReturn().getResponse().getContentAsString();
        log.info(contentAsString);
    }
}

"可以直接这样,不用使用 http://ip:port 了,这样测试更方便"

在这里插入图片描述

(选用)开启所有测试类的数据事务回滚

在这里插入图片描述

//配置事务的回滚,对数据库的增删改都会回滚,便于测试用例的循环利用

@Transactional
@Rollback
public class Test {
 
}

上面两句的作用是,让我们对数据库的操作会事务回滚,如对数据库的添加操作,在方法结束之后,会撤销我们对数据库的操作。

为什么要事务回滚?

测试过程对数据库的操作,会产生脏数据,影响我们数据的正确性
不方便循环测试,即假如这次我们将一个记录删除了,下次就无法再进行这个Junit测试了,因为该记录已经删除,将会报错。
如果不使用事务回滚,我们需要在代码中显式的对我们的增删改数据库操作进行恢复,将多很多和测试无关的代码 
介绍如何使用"断言(Assert)语句 "判别测试结果。

使用Assert类的静态方法,assertEquals(),包含两个参数,左边是预期值,右边是实际值。当预期值与实际值不同时便会报错。

package com.junit.MyClass;

import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Created by lesley on 2017/1/14.
 */
public class CalculatorTest {
    //注意这个不能忘记!!要不然后面无法调用
    private Calculator calculator;
    @Before
    public void setUp() throws Exception {
        calculator = new Calculator();
    }

    @Test
    public void add() throws Exception {
        assertEquals(calculator.add(3, 5),8);
    }

}
package com.teachertom.test;

import com.teachertom.calculator.Calculator;
import org.junit.Assert;
import org.junit.Test;

public class CalculatorTest {
    @Test
    public void testAdd(){
    
        Calculator calculator=new Calculator();
        Assert.assertEquals(10,calculator.add(5,5));
    }

    @Test
    public void testSubtract(){
        Calculator calculator=new Calculator();
        Assert.assertEquals(5,calculator.subtract(10,5));
    }
}

点击运行,实际值与预期值相符,测试通过。
在这里插入图片描述

如果不相符,则会出现下列字样。

在这里插入图片描述

其他基本注解补充
2Junit基本注解介绍
//在所有测试方法前执行一次,一般在其中写上整体初始化的代码
@BeforeClass

//在所有测试方法后执行一次,一般在其中写上销毁和释放资源的代码 
@AfterClass

//在每个测试方法前执行,一般用来初始化方法(比如我们在测试别的方法时,类中与其他测试方法共享的值已经被改变,为了保证测试结果的有效性,我们会在@Before注解的方法中重置数据)
@Before

//在每个测试方法后执行,在方法执行完成后要做的事情
@After

// 测试方法执行超过1000毫秒后算超时,测试将失败
@Test(timeout = 1000)

// 测试方法期望得到的异常类,如果方法执行没有抛出指定的异常,则测试失败
@Test(expected = Exception.class)

// 执行测试时将忽略掉此方法,如果用于修饰类,则忽略整个类
@Ignore("not ready yet")
@Test

@RunWithJUnit中有很多个Runner,他们负责调用你的测试代码,每一个Runner都有各自的特殊功能,你要根据需要选择不同的Runner来运行你的测试代码。
如果我们只是简单的做普通Java测试,不涉及Spring Web项目,你可以省略@RunWith注解,这样系统会自动使用默认Runner来运行你的代码。

5、如何运行一堆"测试类"
方式二:看图如下

在这里插入图片描述

方式一:新建一个测试类–>用于所有测试类

正常情况下我们写了5个测试类,我们需要一个一个执行。
打包测试,就是新增一个类,然后将我们写好的其他测试类配置在一起,然后直接运行这个类就达到同时运行其他几个测试的目的。

@RunWith(Suite.class) 
@SuiteClasses({ATest.class, BTest.class, CTest.class}) 
public class ABCSuite {
    // 类中不需要编写代码
} 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值