项目测试总结

  • 1. 单元测试
  • JUnit
  • 1.1 JUnit基本使用
  • 1. 常用注解
  • 2. Assert断言类
  • 3. 使用步骤
  • 在pom.xml中引入JUnit依赖
  • 创建测试类和测试方法
  • 4. 高级使用
  • 超时测试
  • 异常测试
  • 参数化测试
  • 5. 细节
  • 1.2 Spring、Spring boot 整合 JUnit4
  • 1. 引入pom依赖
  • 2. 创建测试类
  • spring项目
  • springboot 项目
  • 2. 接口测试
  • 1. 常用接口测试方式
  • 2. Knifej 基本使用
  • 引入依赖
  • Knife4j 相关配置
  • 常用注解
  • 限制请求方式
  • 导出离线API文档
  • 3. 并发测试
  • Jmeter简介
  • Jmeter的下载和安装
  • 运行Jmeter
  • 进行并发测试


1. 单元测试

JUnit

JUnit是一个Java语言的单元测试框架,Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何完成功能和完成什么样的功能,Junit是一套框架,继承TestCase类,就可以用Junit进行自动测试。

1.1 JUnit基本使用

1. 常用注解

@BeforeClass:针对所有测试,只执行一次,且必须为static void

@Before:初始化方法,执行当前测试类的每个测试方法前执行。

@Test:修饰测试方法
@Test(excepted=xxx.class):xxx.class 为异常类,表示测试的方法抛出此异常时,认为是正常通过测试
@Test(timeout = 毫秒数) :测试方法执行时间是否符合预期

@After:释放资源,执行当前测试类的每个测试方法后执行

@AfterClass:针对所有测试,只执行一次,且必须为static void

@Ignore:忽略的测试方法(只在测试类的时候生效,单独执行该测试方法无效)

@RunWith:可以更改测试运行器 ,缺省值为: org.junit.runner.Runner

@Parameters:参数化注解

2. Assert断言类

主要方法:

void assertEquals(boolean expected, boolean actual):检查预期值和实际值是否相等

void assertTrue(boolean condition):检查条件为真

void assertFalse(boolean condition):检查条件为假

void assertNotNull(Object object):判断对象是否不为空

void assertNull(Object object):判断对象是否不为空

void assertSame(Object expected, Object actual):判断两个对象是否指向同一个对象

void assertNotSame(Object expected, Object actual):判断两个对象是否不指向同一个对象

void assertArrayEquals(expectedArray, resultArray):判断两个数组是否相等

方法执行成功,则测试通过,执行失败则测试失败

3. 使用步骤
在pom.xml中引入JUnit依赖
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
    <version>4.12</version>
</dependency>
创建测试类和测试方法
  1. 测试类的的命名规则一般是 xxxTest.java
  2. 测试方法上加上 @Test注解。
  3. [快捷生成单元测试]

IDEA 中,选中当前类名,使用快捷键 ALT + ENTER(WIN),选择 Create Test 回车,即可进入生成测试类的选项中,再次回车,就快速的生成测试类。

  1. 生成的测试类在 src/test 目录下,而测试类和源代码的包名是一致的。

以下是测试类示例:

public class HelloServiceImplTest {

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void say() {
	}
}
4. 高级使用
超时测试

通过timeout 参数和 @Test注释一起使用实现: @test(timeout)

如果一个测试用例比起指定的毫秒数花费了更多的时间,那么 Junit 将自动将它标记为失败。

示例:

//以下测试会失败,在一秒后会抛出异常 org.junit.runners.model.TestTimedOutException: test timed out after 1000 milliseconds
@Test(timeout = 1000)
public void testTimeout() throws InterruptedException {
    TimeUnit.SECONDS.sleep(2);
    System.out.println("Complete");
}
异常测试

可以测试代码是否它抛出了想要得到的异常。通过expected 参数和 @Test 注释一起使用实现: @Test(expected)

@Test(expected = NullPointerException.class)
public void testNullException() {
    throw new NullPointerException();
}
参数化测试

Junit 4 引入了一个新的功能参数化测试。参数化测试允许开发人员使用不同的值反复运行同一个测试。

通过以下 5 个步骤来创建参数化测试。

  1. 用 @RunWith(Parameterized.class)来注释 test 类。
  2. 创建一个由 @Parameters 注释的公共的静态方法,它返回**一个对象的集合(数组)**来作为测试数据集合。
  3. 创建一个公共的构造函数,它接受和一行测试数据相等同的东西。
  4. 为每一列测试数据创建一个实例变量。
  5. 用实例变量作为测试数据的来源来创建你的测试用例。

示例:

//1.更改默认的测试运行器为RunWith(Parameterized.class)
@RunWith(Parameterized.class)
public class ParameterTest {
    // 2.声明变量存放预期值和测试数据
    private String firstName;
    private String lastName;
//3.声明一个返回值 为Collection的公共静态方法,并使用@Parameters进行修饰
@Parameterized.Parameters //
public static List<Object[]> param() {
    // 这里我给出两个测试用例
    return Arrays.asList(new Object[][]{{"Mike", "Black"}, {"Cilcln", "Smith"}});
}

//4.为测试类声明一个带有参数的公共构造函数,并在其中为之声明变量赋值
public ParameterTest(String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}
// 5. 进行测试,发现它会将所有的测试用例测试一遍
@Test
public void test() {
    String name = firstName + " " + lastName;
    assertThat("Mike Black", is(name));
}

}

5. 细节
  1. 一个单元测试类中各注解的执行顺序如下:
@BeforeClass –> @Before –> @Test–> @After –> @AfterClass

2. 每一个测试方法的调用顺序为:

@Before –> @Test –> @After

1.2 Spring、Spring boot 整合 JUnit4

Spring 框架提供了一个专门的测试模块(spring-test),用于应用程序的集成测试。 在 Spring Boot 中,你可以通过spring-boot-starter-test启动器快速开启和使用它。

1. 引入pom依赖

spring项目:

<!--junit依赖-->
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
</dependency>
<!--spring整合junit-->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <version>5.1.9.RELEASE</version>
</dependency>

springboot项目:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
2. 创建测试类
spring项目
//使用Spring整合Junit专用的类加载器
@RunWith(SpringJUnit4ClassRunner.class)
//加载Spring配置文件或者配置类
@ContextConfiguration(classes = {SpringConfiguration.class}) //加载配置类
//@ContextConfiguration(locations={"classpath:applicationContext.xml"})//加载配置文件
public class AccountServiceTest {
    //支持自动装配注入bean
    @Autowired
    private AccountService accountService;

    @Test
    public void testFindById(){
        System.out.println(accountService.findById(1));
    }
    
    @Test
    public void testFindAll(){
        System.out.println(accountService.findAll());
    }
}

以上方式中优化了原始Spring项目中JUnit单元测试类的测试方法总需要先创建IOC容器调用getBean获取对象的步骤,即以下重复代码:

ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
 BookDao bookDao =(BookDao)ac.getBean("bookDao");

通过将Junit加载Spring的配置类,让Junit负责创建Spring容器,仅仅将配置文件的名称告诉它之后测试方法中需要进行测试的Bean就可以直接在测试类中进行注入

springboot 项目
// 获取启动类,加载配置,确定装载 Spring 程序的装载方法,它回去寻找 主配置启动类(被 @SpringBootApplication 注解的)
@SpringBootTest
// 让 JUnit 运行 Spring 的测试环境, 获得 Spring 环境的上下文的支持
@RunWith(SpringRunner.class)
public class EmployeeServiceImplTest {
    // do 
    @Test
    public void test(){
        Calculate calculate = new Calculate();
        int add = calculate.add(1, 2);
        System.out.println(add);
    }
}

2. 接口测试

1. 常用接口测试方式

Postman、Apifox等测试软件;

Knife4j:

Knife4j 是集Swagger2 和 OpenAPI3 为一体的增强解决方案,前身是 swagger-bootstrap-ui,致力于 springfox-swagger 的增强 UI 实现。

java 测试nacos 配置内容_java 测试nacos 配置内容

2. Knifej 基本使用

引入依赖

主要与springboot的版本对应,以下依赖版本建议

  • Spring Boot 版本建议 2.4.0~3.0.0之间
  • Spring Boot 版本 < 2.4 版本则建议选择Knife4j 4.0之前的版本
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
    <version>4.3.0</version>
</dependency>
Knife4j 相关配置
# springdoc-openapi项目配置 非必须
springdoc:
  swagger-ui:
    path: /swagger-ui.html
    tags-sorter: alpha
    operations-sorter: alpha
  api-docs:
    path: /v3/api-docs
  group-configs:
    - group: 'default'
      paths-to-match: '/**'
      packages-to-scan: com.xiaominfo.knife4j.demo.web
# knife4j的增强配置
knife4j:
  enable: true  #此项必配置,否则knife4j运行有问题 
  setting:
    language: zh_cn
常用注解
  1. @Api注解

添加在控制器类上的注解,通过此注解的tags属性可以修改原本显示控制器类名称的位置的文本,通常,建议在配置的tags属性值上添加序号,例如:“01. 用户模块”、“02. 微博模块”,则框架会根据值进行排序。

参数说明:

tags:配置模块名称

代码示例:

// 1. UserController
@Api(tags = "01.用户管理模块")
public class UserController {...}

// 2. WeiboController
@Api(tags = "02.微博管理模块")
public class WeiboController {...}

// 3. CommentController
@Api(tags = "03.评论管理模块")
public class CommentController {...}

文档效果(重启工程并刷新页面:http://localhost:8080/doc.html#/home)

java 测试nacos 配置内容_java 测试nacos 配置内容_02

  1. @ApiOperation注解

添加在控制器类中处理请求的方法上的注解,用于配置此方法处理的请求在API文档中显示的文本。

参数说明

value:配置业务名称

代码示例:

此处以注册功能为例,其他所有方法请添加说明

/**注册功能*/
@PostMapping("/reg")
@ApiOperation(value = "注册功能", notes="测试测试注册功能")
public int reg(@RequestBody UserRegDTO userRegDTO){...}

java 测试nacos 配置内容_java_03

  1. @ApiModelProperty注解

是添加在实体类的属性上的注解,用于对请求参数或响应结果中的某个属性进行说明,
主要通过其value属性配置描述文本,并可通过example属性配置示例值。

参数说明

value属性:配置参数名称
required属性:配置是否必须提交此请求参数
example属性:配置示例值
注意:如果配置了 required=true,只是一种显示效果,Knife4j框架并不具备检查功能

代码示例

以注册功能UserRegDTO为例

@Data
public class UserRegDTO {
    @ApiModelProperty(value = "用户名", required = true, example = "赵丽颖")
    private String username;
    @ApiModelProperty(value = "密码", required = true)
    private String password;
    @ApiModelProperty(value = "昵称", required = true)
    private String nickname;
}

文档效果(重启工程并刷新页面:http://localhost:8080/doc.html#/home)

java 测试nacos 配置内容_Test_04

  1. @ApiImplicitParam注解

添加在控制器类中处理请求的方法上的注解,主要用于配置非封装(非XxxDTO/XxxParam的参数)的参数

参数说明

name:指定参数名称(参数变量名)
value:配置参数名称
dataType:配置数据类型
required:配置是否必须提交此请求参数
example:配置参数的示例值
注意:一旦使用此注解,各个参数的数据类型默认都会显示String,可以通过dataType指定数据类型

代码示例

此处以微博详情功能为例

@ApiImplicitParam(name = "id", value = "微博", required=true, dataType = "int")
public WeiboDetailVO selectById(int id){...}

java 测试nacos 配置内容_java 测试nacos 配置内容_05

  1. @ApiImplicitParams注解

添加在控制器类中处理请求的方法上的注解,当方法有多个非封装的参数时,在方法上添加此注解,并在注解内部通过@ApiImplicitParam数组配置多个参数。

代码示例:

/**微博详情页功能*/
@GetMapping("selectById")
@ApiOperation(value = "微博详情功能")
@ApiImplicitParams(value = {
    @ApiImplicitParam(name = "id", value = "微博", required=true, dataType = "int"),
    @ApiImplicitParam(name = "username", value = "用户名", required=true)
})
// 额外增加username参数,仅仅用于测试
public WeiboDetailVO selectById(int id, String username){
    return weiboMapper.selectById(id);
}
// 带上传的参数的情况
@ApiOperation(value = "uploadExcel", notes = "上传excel文件进行解析")
@ApiImplicitParams(        
	{  @ApiImplicitParam(value = "上传文件", required = true) 
    })
@PostMapping("/uploadExcel")
public HttpResp<String> uploadExcel(@RequestPart @RequestParam("excel")MultipartFile excel) {    

		String originalFilename = excel.getOriginalFilename();    
		log.debug("上传文件名称: {}",originalFilename);    
		return new HttpResp<>(200,"success",originalFilename+"上传成功",LocalDate.now());
}

文档效果(重启工程并刷新页面:http://localhost:8080/doc.html#/home)

java 测试nacos 配置内容_Test_06

  1. @ApiIgnore注解

添加在处理请求的方法的参数上,用于表示API文档框架应该忽略此参数

代码示例

// 参数中添加@ApiIgnore注解
public int insert(@RequestBody WeiboDTO weiboDTO, @ApiIgnore HttpSession session){...}

java 测试nacos 配置内容_java_07

限制请求方式

API文档中默认每个功能会展示7种请求方式,遵循RESTful规则将 @RequestMapping 注解修改为对应请求方法的注解,比如:@GetMapping @PostMapping @PutMapping @DeleteMapping 注解,重启工程后刷新测试。

导出离线API文档

文档管理 - 离线文档 中存在多种格式的导出格式

选择合适的文档格式,导出即可到本地磁盘

3. 并发测试

Jmeter简介

Apache JMeter是Apache组织开发的基于Java的压力测试工具。JMeter 可以用于对服务器、网络或对象模拟巨大的负载,来自不同压力类别下测试它们的强度和分析整体性能。
另外,JMeter能够对应用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。

Jmeter的下载和安装

下载地址:https://jmeter.apache.org/download_jmeter.cgi

java 测试nacos 配置内容_spring_08

运行Jmeter

进入安装路径的bin目录下执行 jmeter.bat

java 测试nacos 配置内容_笔记_09

进行并发测试
  1. 创建线程组:右键测试计划,添加一个线程组,可以设置对应多少秒有多少个线程数来访问这个接口

java 测试nacos 配置内容_java 测试nacos 配置内容_10

java 测试nacos 配置内容_Test_11

  1. 添加HTTP请求

java 测试nacos 配置内容_spring_12

  1. 添加Http请求的响应

java 测试nacos 配置内容_spring_13

  1. 设置Http请求路径

java 测试nacos 配置内容_spring_14

  1. 查看结果

java 测试nacos 配置内容_java_15