7.5 KiB
7.5 KiB
3.4 系统测试
为确保系统交付质量,我制定并执行了一套覆盖从代码单元到用户场景、从功能正确性到非功能性需求的、多层次、全方位的测试策略。
3.4.1 后端测试
我主要负责后端的单元测试、集成测试和API接口测试,旨在从源头保证服务的稳定、可靠与安全。
1. 单元测试 (Unit Testing)
我坚持“测试驱动开发”(TDD)的理念,使用JUnit 5和Mockito框架为核心的Service层和Repository层的公共方法编写了详尽的单元测试。单元测试的目标是隔离验证最小代码单元(一个方法或一个类)的逻辑正确性。
测试用例示例:TaskAssignmentService单元测试
@ExtendWith(MockitoExtension.class)
class TaskAssignmentServiceTest {
@Mock
private FeedbackRepository feedbackRepository;
@Mock
private UserAccountRepository userAccountRepository;
@Mock
private TaskRepository taskRepository;
@Mock
private AssignmentRepository assignmentRepository;
@InjectMocks
private TaskAssignmentServiceImpl taskAssignmentService;
@Test
void assignTask_Success_ShouldReturnSavedAssignment() {
// Arrange: 准备测试数据和模拟行为
Feedback mockFeedback = new Feedback(1L, "Test", "Desc", FeedbackStatus.CONFIRMED, 101L);
UserAccount mockAssignee = new UserAccount(202L, "worker", "pass", Role.GRID_WORKER);
when(feedbackRepository.findById(1L)).thenReturn(Optional.of(mockFeedback));
when(userAccountRepository.findById(202L)).thenReturn(Optional.of(mockAssignee));
when(taskRepository.save(any(Task.class))).thenAnswer(i -> i.getArgument(0));
when(assignmentRepository.save(any(Assignment.class))).thenAnswer(i -> i.getArgument(0));
// Act: 执行被测试的方法
Assignment result = taskAssignmentService.assignTask(1L, 202L, 303L);
// Assert: 验证结果和交互
assertNotNull(result);
assertEquals(202L, result.getAssigneeId());
verify(feedbackRepository, times(1)).save(any(Feedback.class)); // 验证Feedback状态是否被更新并保存
assertEquals(FeedbackStatus.ASSIGNED, mockFeedback.getStatus());
}
@Test
void assignTask_FeedbackNotFound_ShouldThrowException() {
// Arrange
when(feedbackRepository.findById(99L)).thenReturn(Optional.empty());
// Act & Assert
assertThrows(IllegalArgumentException.class, () -> {
taskAssignmentService.assignTask(99L, 202L, 303L);
});
}
}
测试策略说明:
- Mocking: 使用
Mockito框架模拟(Mock)外部依赖(如各个Repository),使得测试可以专注于Service层自身的业务逻辑,而不受数据库或文件系统的影响。 - 覆盖度: 我为每个公共方法都编写了多个测试用例,覆盖了“成功路径”和各种“异常路径”(如输入非法、依赖返回空等),力求达到较高的代码覆盖率和逻辑覆盖率。
2. API接口测试 (API Testing)
我利用SpringDoc与Swagger UI的无缝集成,以及更专业的API测试工具Postman,对所有RESTful API进行了系统性的黑盒测试。
- 测试范围: 覆盖了用户认证、权限管理、反馈生命周期、任务生命周期等所有核心模块的每一个API端点。
- 测试方法: 我为每个API编写了一系列测试用例,形成了一个
Postman测试集(Collection),这使得测试可以被保存、共享和重复执行。
API测试用例表示例 (扩展):
| 用例ID | 模块 | 接口 | 场景描述 | 输入数据 | 预期HTTP状态 | 预期响应体关键内容 | 结果 |
|---|---|---|---|---|---|---|---|
| TC-API-001 | 任务管理 | POST /api/assignments |
成功分配任务 | 合法的feedbackId, assigneeId |
201 Created |
返回新创建的assignment对象JSON |
通过 |
| TC-API-002 | 任务管理 | POST /api/assignments |
异常:反馈ID不存在 | feedbackId: 9999 |
404 Not Found |
"message": "Feedback with id 9999 not found" |
通过 |
| TC-API-003 | 任务管理 | POST /api/assignments |
异常:指派的用户不是网格员 | assigneeId指向一个ADMIN角色的用户 |
400 Bad Request |
"message": "User is not a grid worker" |
通过 |
| TC-API-004 | 任务管理 | POST /api/assignments |
异常:反馈状态不正确 | feedbackId指向一个PENDING状态的反馈 |
400 Bad Request |
"message": "Feedback is not in a CONFIRMED state" |
通过 |
| TC-API-005 | 安全 | POST /api/assignments |
安全:无JWT令牌 | Authorization头为空 |
401 Unauthorized |
(空或错误提示) | 通过 |
| TC-API-006 | 安全 | POST /api/assignments |
安全:使用网格员角色的JWT | Authorization头为一个GRID_WORKER的JWT |
403 Forbidden |
(空或错误提示) | 通过 |
3.4.2 前端测试
我与负责前端的组员紧密协作,进行了全面的前端功能、UI/UX和兼容性测试。
- 手工功能测试: 我们以用户故事(User Story)为驱动,模拟不同角色的用户(公众、网格员、主管、管理员),完整地执行了所有核心业务流程的端到端场景,确保功能符合需求规格。
- UI/UX测试: 仔细检查了界面的布局、色彩、字体、图标和交互动效,确保其在主流浏览器(Chrome, Firefox, Edge)的不同版本和不同屏幕分辨率下(如
1920x1080,1366x768)都能保持良好的一致性、美观度和用户体验。
3.4.3 集成与系统测试
在前后端分别完成各自的测试后,我们将整个系统部署到一台独立的测试服务器上,进行了端到端的集成测试和系统测试。
- 目的: 验证前后端数据接口的正确性、API调用的顺畅性、以及在真实网络环境下整个系统业务流程的闭环。
- 过程: 我们共同执行了一套预先设计的系统级测试用例,这些用例模拟了真实世界中的复杂操作序列。例如:
- 公众用户A提交反馈 -> 主管B审核通过 -> 主管B将任务分配给网格员C -> 网格员C完成任务并提交数据 -> 主管B查看已完成的任务和数据。
- 并发测试:多个用户同时提交反馈或更新任务,验证后端
synchronized机制是否有效防止了数据冲突。
- 结果: 通过严格的集成联调测试,我们发现并修复了若干在单元测试阶段难以暴露的问题(如跨域CORS配置问题、序列化/反序列化日期格式不一致问题、JWT刷新逻辑的边界条件等),最终确保了前后端系统的无缝集成和稳定运行。
3.4.4 非功能性测试
除了功能测试,我还对系统的部分非功能性需求进行了初步的探索性测试。
- 性能测试: 使用
Apache JMeter工具,对核心的登录和查询类API进行了简单的压力测试。模拟20个并发用户持续请求,观察到API的平均响应时间仍在200ms以内,CPU和内存占用率处于合理范围,初步证明系统具备应对一定并发访问的能力。 - 安全测试:
- 权限测试: 严格测试了不同角色的用户访问未授权API的情况,验证系统是否能正确返回
403 Forbidden。 - 输入验证: 尝试提交包含恶意脚本(XSS)或SQL注入(虽然我们不是SQL数据库,但原理相通)的表单数据,验证后端是否有充分的输入清理和验证机制。
- 权限测试: 严格测试了不同角色的用户访问未授权API的情况,验证系统是否能正确返回