既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
三. JUnit回顾
1. JUnit简介
JUnit 是一个回归测试框架,经常被Java开发者用于实施对应用程序的单元测试,加快程序编制速度,同时提高编码的质量。
ps:
回归测试是指修改了旧代码后,重新进行测试以确认本次修改没有引入新的错误或导致其他代码产生错误,也就是要重复以前的全部或部分相同测试。
2. JUnit特性
- 测试工具
- 测试套件
- 测试运行器
- 测试分类
3. JUnit测试使用
3.1 添加依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<version>4.12</version>
</dependency>
3.2 创建测试类和测试方法
- 测试类的命名规则一般是 xxxTest.java;
- 测试类中的测试方法一般都有前缀,比如在测试方法上带有test前缀;
- 在测试方法上添加@Test注解。
4. JUnit中常用注解
- @BeforeClass:针对所有测试,只执行一次,且修饰符必须为static void。
- @Before:初始化方法,在执行当前测试类的每个测试方法前执行。
- @Test:测试方法,在这里可以测试期望的异常和超时时间。
- @After:释放资源,在执行当前测试类的每个测试方法后执行。
- @AfterClass:针对所有测试,只执行一次,且必须为static void。
- @Ignore:忽略的测试方法(只在测试类的时候生效,单独执行该测试方法无效)。
- @RunWith: 更改测试运行器,缺省值org.junit.runner.Runner
5. 单元测试类执行顺序
@BeforeClass –> @Before –> @Test –> @After –> @AfterClass
6. 测试方法的调用顺序
@Before –> @Test –> @After
7. JUnit中的异常测试
我们可以利用@Test注解和expected 参数,来测试我们的代码中是否会抛出某个可能的异常。
@Test(expected = NullPointerException.class)
public void testNullException() {
throw new NullPointerException();
}
8. JUnit中的超时测试
我们可以利用@Test注解和timeout参数,来测试我们的代码是否比指定的毫秒数花费了更多的时间。
@Test(timeout = 1000)
public void testTimeout() throws InterruptedException {
TimeUnit.SECONDS.sleep(2);
System.out.println("Success");
}
9. JUnit中的套件测试
我们可以利用@Suite.SuiteClasses注解,将多个测试类整合在一起,形成一个测试套件进行测试。
public class TaskOneTest {
@Test
public void test() {
System.out.println("任务一...");
}
}
public class TaskTwoTest {
@Test
public void test() {
System.out.println("任务二...");
}
}
public class TaskThreeTest {
@Test
public void test() {
System.out.println("任务三...");
}
}
// 1. 更改测试运行方式为 Suite
@RunWith(Suite.class)
// 2. 将测试类传入进来
@Suite.SuiteClasses({TaskOneTest.class, TaskTwoTest.class, TaskThreeTest.class})
public class SuitTest {
/**
* 测试套件的入口类只是组织测试类一起进行测试,无任何特别的测试方法。
*/
}
10. JUnit中的参数化测试
从Junit 4开始,引入了一个新的参数化测试功能。参数化测试允许开发人员使用不同的值反复运行同一个测试方法。
我们可以遵循以下 5个步骤来创建参数化测试方法。
- 用 @RunWith(Parameterized.class)来注解 test 类;
- 创建一个由 @Parameters 注解的公共静态方法,返回**一个对象的集合(数组)**来作为测试参数的数据集合;
- 创建一个公共的构造函数,接收和测试数据相等的内容;
- 为每一个测试数据创建一个实例变量;
- 用实例变量作为测试数据的来源来创建你的测试用例。
//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));
}
}
11. JUnit中使用assertThat断言
JUnit 4.4 结合 Hamcrest 提供了一个全新的断言语法——assertThat。
#语法
assertThat( [actual], [matcher expected] );
assertThat 使用了 Hamcrest 的 Matcher 匹配符,用户可以使用匹配符规定的匹配规则,来精确的指定一些想要设定满足的条件,具有很强的易读性,而且使用起来更加灵活。
四. SpringBoot中的测试功能
1. SpringBoot中的测试依赖包
Spring 框架提供了一个专门的测试模块(spring-test),用于应用程序的集成测试。而在 Spring Boot 中,我们可以通过spring-boot-starter-test启动器快速开启和使用它。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2. 创建测试类
// 获取SpringBoot启动类,加载配置,确定装载 Spring 程序的装载方法,它会去寻找 主配置启动类(也就是被 @SpringBootApplication 注解的类)
@SpringBootTest
// 让 JUnit 运行 Spring 的测试环境,获得 Spring 上下文环境的支持。
@RunWith(SpringRunner.class)
public class OrderTest {
// ...
}
3. SpringBoot中实现测试的方式
在SpringBoot中实现测试功能,我们可以利用以下4种方式进行相关的测试实现。
- **@WebMvcTest注解:**针对单个的Spring MVC控制器实现单元测试,该方式不需要完整启动 HTTP 服务器就可以快速测试 MVC 控制器;
- **@SpringBootTest注解:**该方式可以启动一个完整的 HTTP 服务器,对整个Spring Boot 的 Web 应用编写测试代码。
- **@DataJpaTest注解:**使用 @DataJpaTest注解表示只对 JPA 进行测试。
- **Mockito方式:**对于一些不容易构造的、或者和这次单元测试无关但是上下文又有依赖的对象,用一个虚拟的对象(Mock对象)来模拟,以便单元测试能够进行。
4. @WebMvcTest注解对单个Controller进行单元测试
如果我们想对 Spring MVC 控制器编写单元测试代码时,可以使用@WebMvcTest注解。它提供了自配置的 MockMvc,可以不需要完整启动 HTTP 服务器,就能够快速测试 MVC 控制器。
4.1 构建一个测试用的Controller
@RestController
@RequestMapping(value = "/order", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping
public ResponseEntity<List<OrderResult>> listAll() {
return ResponseEntity.ok(orderService.findOrders());
}
}
4.2 编写 MockMvc 的测试类
@RunWith(SpringRunner.class)
@WebMvcTest(OrderController.class)
public class OrderControllerTest {
@Autowired
private MockMvc mvc;
@MockBean
private OrderService orderService;
public void setUp() {
// 数据打桩,设置该方法返回的 body一直是空的
Mockito.when(orderService.findOrders())
.thenReturn(new ArrayList<>());
}
@Test
public void listAll() throws Exception {
mvc.perform(MockMvcRequestBuilders
.get("/order"))
.andExpect(status().isOk()) // 期待返回状态吗码200
// JsonPath expression https://github.com/jayway/JsonPath
//.andExpect(jsonPath("$[1].name").exists()) // 这里是期待返回值是数组,并且第二个值的 name 存在,所以这里测试是失败的
.andDo(print()); // 打印返回的 http response 信息
}
}
注意
在我们使用@WebMvcTest注解时,只有部分Bean 能够被扫描得到,它们分别是:
- @Controller
- @ControllerAdvice
- @JsonComponent
- Filter
- WebMvcConfigurer
- HandlerMethodArgumentResolver
其他常规的@Component(包括@Service、@Repository等)Bean 则不会被加载到 Spring 的测试上下文环境中。
4.3 注入Spring上下文环境到 MockMvc中
可以如下编写 MockMvc 的测试类:
@RunWith(SpringRunner.class)
@SpringBootTest
public class OrderControllerTest {
/**
* Interface to provide configuration for a web application.
*/
@Autowired
private WebApplicationContext ctx;
private MockMvc mockMvc;
/**
* 初始化 MVC 的环境
*/
@Before
public void before() {
//使用 WebApplicationContext构建 MockMvc
mockMvc = MockMvcBuilders.webAppContextSetup(ctx).build();
}
@Test
public void listAll() throws Exception {
mockMvc.perform(get("/order") // 测试的相对地址
.accept(MediaType.APPLICATION_JSON_UTF8))// accept response content type
.andExpect(status().isOk()) // 期待返回状态吗码200
// JsonPath expression https://github.com/jayway/JsonPath
.andExpect(jsonPath("$[1].name").exists()) // 这里是期待返回值是数组,并且第二个值的 name 存在
.andDo(print()); // 打印返回的 http response 信息
}
}
5. @SpringBootTest测试完整Web应用
当我们想启动一个完整的 HTTP 服务器,对 Spring Boot 的 Web 应用编写测试代码时,可以使用@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
注解开启一个随机的可用端口。
Spring Boot 针对 REST 调用的测试,提供了一个 TestRestTemplate 模板,它可以解析链接服务器的相对地址。
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class OrderControllerTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void listAll() {
// 由于这里返回的是 List 类型数据,可以使用 exchange 函数进行类型转换。
ParameterizedTypeReference<List<OrderResult>> type = new ParameterizedTypeReference<List<OrderResult>>() {};
ResponseEntity<List<OrderResult>> result = restTemplate.exchange("/order", HttpMethod.GET, null, type);
Assert.assertThat(result.getBody().get(0).getName(), Matchers.notNullValue());
}
}
6. @DataJpaTest测试JPA
我们可以使用 @DataJpaTest注解对 JPA 进行测试,其中@DataJpaTest注解只会扫描@EntityBean和装配了Spring Data JPA 的存储库,其他常规的@Component(包括@Service、@Repository等)Bean 则不会被加载到 Spring 的上下文测试环境中。
@DataJpaTest 提供了两种测试方式:
- 使用内存数据库 h2Database,Spring Data Jpa 测试默认采取的就是这种方式;
- 使用真实环境的数据库。
6.1 使用内存数据库测试
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
了两种测试方式:
- 使用内存数据库 h2Database,Spring Data Jpa 测试默认采取的就是这种方式;
- 使用真实环境的数据库。
6.1 使用内存数据库测试
[外链图片转存中…(img-Yro0C5cq-1715878076788)]
[外链图片转存中…(img-9IEUL5pu-1715878076788)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!