国庆节10月1日
--


软件测试阶段划分、测试方法分类、JUnit单元测试入门、断言、常用注解及依赖范围
测试是一种用来促进鉴定软件正确性、完整性、安全性和质量的过程。

| 阶段 | 说明 | 目的 | 测试人员 |
|---|---|---|---|
| 单元测试 | 对软件最小组成单位进行测试 | 检验基本组成单位的正确性 | 开发人员 |
| 集成测试 | 将通过测试的单元组合后测试 | 检查单元之间的协作是否正确 | 开发人员 |
| 系统测试 | 对集成好的软件系统进行彻底测试 | 验证正确性、性能是否满足要求 | 测试人员 |
| 验收测试 | 针对用户需求、业务流程的正式测试 | 验证是否满足验收标准 | 客户/需求方 |

| 方法 | 说明 |
|---|---|
| 白盒测试 | 清楚软件内部结构和代码逻辑,用于验证代码和逻辑正确性 |
| 黑盒测试 | 不清楚内部结构,用于验证功能、兼容性、验收测试 |
| 灰盒测试 | 结合白盒和黑盒,既关注内部结构又考虑外部表现 |

JUnit 是最流行的 Java 测试框架之一。相比在 main 方法中测试,JUnit 具有以下优势:

| main 方法测试的问题 | JUnit 的优势 |
|---|---|
| 测试代码与源代码未分开,难维护 | 测试代码与源代码分离,便于维护 |
| 一个方法测试失败影响后面方法 | 各测试方法独立运行 |
| 无法自动化测试,得不到测试报告 | 可自动化测试,自动产出测试报告 |
引入依赖(pom.xml):
1<dependency>2 <groupId>org.junit.jupiter</groupId>3 <artifactId>junit-jupiter</artifactId>4 <version>5.9.1</version>5 <scope>test</scope>6</dependency>编写测试类(src/test/java 目录下):
1@Test2public void testGetAge() {3 Integer age = new UserService().getAge("110002200505091218");4 System.out.println(age);5}命名规范:
XxxTestpublic void xxx() { ... }JUnit 提供断言方法,验证被测试方法是否按预期工作。
1@Test2public void testGetAge() {3 Integer age = new UserService().getAge("110002200505091218");4 Assertions.assertNotEquals(18, age, "两个值相等");5}6
7@Test8public void testGetGender() {9 String gender = new UserService().getGender("612429198904201611");10 Assertions.assertEquals("男", gender);11}
| 注解 | 说明 |
|---|---|
@Test | 标记方法为测试方法 |
@BeforeEach | 每个测试方法执行前运行 |
@AfterEach | 每个测试方法执行后运行 |
@BeforeAll | 所有测试方法执行前运行一次(必须 static) |
@AfterAll | 所有测试方法执行后运行一次(必须 static) |
@DisplayName | 指定测试类或方法的显示名称 |
@ParameterizedTest | 标记为参数化测试方法 |
@ValueSource | 为参数化测试提供数据源 |
生命周期注解示例:
1public class UserServiceTest {2
3 @BeforeEach4 public void testBefore() {5 System.out.println("before...");6 }7
8 @AfterEach9 public void testAfter() {10 System.out.println("after...");11 }12
13 @BeforeAll14 public static void testBeforeAll() {15 System.out.println("before all ...");16 }17
18 @AfterAll19 public static void testAfterAll() {20 System.out.println("after all...");21 }22
23 @Test24 public void testGetAge() {25 Integer age = new UserService().getAge("110002200505091218");26 System.out.println(age);27 }28}
参数化测试示例:
1@DisplayName("测试-学生业务操作")2public class UserServiceTest {3
4 @DisplayName("测试-获取年龄")5 @Test6 public void testGetAge() {7 Integer age = new UserService().getAge("110002200505091218");8 System.out.println(age);9 }10
11 @DisplayName("测试-获取性别")12 @ParameterizedTest13 @ValueSource(strings = {"612429198904201611", "612429198904201631", "612429198904201626"})14 public void testGetGender(String idcard) {15 String gender = new UserService().getGender(idcard);16 System.out.println(gender);17 }18}
通过 <scope> 标签控制依赖的使用范围:

| scope 值 | 主程序(main) | 测试程序(test) | 打包(package) |
|---|---|---|---|
compile(默认) | ✅ | ✅ | ✅ |
test | ❌ | ✅ | ❌ |
provided | ✅ | ✅ | ❌ |
runtime | ❌ | ✅ | ✅ |
典型用法:JUnit 依赖设置 scope 为 test,表示该依赖仅测试程序可用,主程序中无法使用。
1<dependency>2 <groupId>org.junit.jupiter</groupId>3 <artifactId>junit-jupiter</artifactId>4 <version>5.9.1</version>5 <scope>test</scope>6</dependency>
src/test/java 目录下,与源代码分离。@BeforeAll 和 @AfterAll 方法必须使用 static 修饰。如果你喜欢,那么欢迎来到我的世界!
了解更多暂未播放



"所有的相遇都是久别重逢。"—— 未知


