You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

557 lines
32 KiB

1 month ago
# 测试指南
<cite>
**本文引用的文件**
- [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java)
- [application.yml](file://crm-app/src/main/resources/application.yml)
- [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java)
- [SystemController.java](file://crm-auth/src/main/java/com/crm/auth/controller/SystemController.java)
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java)
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
- [AuthLoginUser.java](file://crm-auth/src/main/java/com/crm/auth/security/AuthLoginUser.java)
- [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java)
- [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java)
- [AuthServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java)
- [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java)
- [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java)
- [DingTalkAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/DingTalkAuthClient.java)
- [ThirdPartyAuthClientFactory.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClientFactory.java)
- [DataScopeIntegrationTest.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/DataScopeIntegrationTest.java)
- [TestOwnedData.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/TestOwnedData.java)
- [TestOwnedDataMapper.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/TestOwnedDataMapper.java)
- [DingTalkAuthClientTest.java](file://crm-auth/src/test/java/com/crm/auth/service/client/DingTalkAuthClientTest.java)
- [ThirdPartyAuthClientFactoryTest.java](file://crm-auth/src/test/java/com/crm/auth/service/client/ThirdPartyAuthClientFactoryTest.java)
- [AuthServiceImplTest.java](file://crm-auth/src/test/java/com/crm/auth/service/impl/AuthServiceImplTest.java)
- [AuthUserServiceImplTest.java](file://crm-auth/src/test/java/com/crm/auth/service/impl/AuthUserServiceImplTest.java)
- [SysDeptServiceImplTest.java](file://crm-auth/src/test/java/com/crm/auth/service/impl/SysDeptServiceImplTest.java)
1 month ago
- [UserListIntegrationTest.java](file://crm-auth/src/test/java/com/crm/auth/service/impl/UserListIntegrationTest.java)
1 month ago
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java)
- [MissingParameterException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/MissingParameterException.java)
- [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java)
- [ResourceNotExistException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/ResourceNotExistException.java)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
- [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java)
- [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java)
- [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java)
- [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java)
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
- [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java)
- [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java)
- [DataVisibilityTest.java](file://crm-base/src/test/java/com/crm/base/security/DataVisibilityTest.java)
- [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java)
- [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
- [FileApiImplTest.java](file://crm-file/src/test/java/com/crm/file/service/impl/FileApiImplTest.java)
- [KkFileViewClientTest.java](file://crm-file/src/test/java/com/crm/file/service/KkFileViewClientTest.java)
- [OrphanChunkCleanupTaskTest.java](file://crm-file/src/test/java/com/crm/file/task/OrphanChunkCleanupTaskTest.java)
</cite>
1 month ago
## 更新摘要
**变更内容**
- 新增用户列表集成测试章节,详细介绍UserListIntegrationTest的使用方法和最佳实践
- 扩展数据权限集成测试部分,补充DataScopeIntegrationTest的测试场景和断言方法
- 更新集成测试策略,增加复杂业务场景的测试覆盖建议
1 month ago
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本测试指南面向CRM后端项目的开发者与测试工程师,目标是建立覆盖单元测试、集成测试、端到端测试的完整体系。文档围绕认证授权、权限控制、文件操作、异常处理等核心能力,给出Mock策略、测试数据准备、测试环境搭建、覆盖率要求与持续集成建议,并补充性能、压力与安全测试的方法与工具推荐,帮助团队构建稳定可靠的测试质量保障流程。
## 项目结构
本项目采用多模块Maven工程:
- crm-app:应用启动入口与全局配置
- crm-auth:认证与权限(控制器、安全配置、服务实现、客户端)
- crm-base:基础能力(异常、结果封装、通用实体、安全上下文、MyBatis-Plus配置等)
- crm-file:文件上传下载与预览、分片清理任务
```mermaid
graph TB
subgraph "应用层"
APP["crm-app<br/>启动类与应用配置"]
end
subgraph "认证与权限"
AUTH_CTRL["AuthController / SystemController"]
AUTH_SEC["SecurityConfig / JwtAuthenticationFilter / TokenService"]
AUTH_SVC["AuthServiceImpl / AuthUserServiceImpl / SysDeptServiceImpl"]
AUTH_CLIENT["DingTalkAuthClient / ThirdPartyAuthClientFactory"]
end
subgraph "基础能力"
BASE_EXC["GlobalExceptionHandlerAdvice / 业务异常类"]
BASE_RESULT["Result / ResultCodeEnum / PageResult"]
BASE_SEC["DataScopeHelper / DataVisibilityContext / SecurityUtils"]
BASE_ENT["BaseEntity / OwnedEntity"]
end
subgraph "文件服务"
FILE_CTRL["FileController"]
FILE_SVC["FileApiImpl / FileInfoServiceImpl"]
FILE_TASK["OrphanChunkCleanupTask"]
FILE_EXT["KkFileViewClient"]
end
APP --> AUTH_CTRL
AUTH_CTRL --> AUTH_SEC
AUTH_CTRL --> AUTH_SVC
AUTH_SVC --> BASE_ENT
AUTH_SEC --> BASE_SEC
AUTH_SVC --> BASE_EXC
AUTH_SVC --> BASE_RESULT
FILE_CTRL --> FILE_SVC
FILE_SVC --> FILE_EXT
FILE_SVC --> BASE_RESULT
FILE_TASK --> FILE_SVC
```
图表来源
- [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java)
- [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java)
- [SystemController.java](file://crm-auth/src/main/java/com/crm/auth/controller/SystemController.java)
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
- [AuthServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java)
- [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java)
- [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java)
- [DingTalkAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/DingTalkAuthClient.java)
- [ThirdPartyAuthClientFactory.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClientFactory.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java)
- [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
- [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java)
- [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java)
- [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java)
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
- [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java)
- [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java)
- [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
章节来源
- [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java)
- [application.yml](file://crm-app/src/main/resources/application.yml)
## 核心组件
- 认证与鉴权
- 控制器:登录、系统信息接口
- 安全配置:JWT过滤器、令牌服务、权限拦截器
- 服务层:用户认证、部门树、角色菜单权限
- 第三方登录:钉钉等OAuth客户端与工厂
- 基础能力
- 统一异常处理与业务异常类型
- 统一返回体与分页对象
- 数据权限上下文与工具方法
- 通用实体基类
- 文件服务
- 文件上传/下载/预览
- 分片清理定时任务
- 外部预览服务客户端
章节来源
- [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java)
- [SystemController.java](file://crm-auth/src/main/java/com/crm/auth/controller/SystemController.java)
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
- [AuthServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java)
- [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java)
- [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java)
1 month ago
- [DingTalkAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/DingTalkAuthAuthClient.java)
1 month ago
- [ThirdPartyAuthClientFactory.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClientFactory.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java)
- [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
- [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java)
- [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java)
- [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java)
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
- [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java)
- [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java)
- [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
## 架构总览
下图展示请求从Web层到安全层、服务层与外部依赖的关键路径,以及异常与返回体的流转。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Controller as "AuthController/SystemController"
participant Filter as "JwtAuthenticationFilter"
participant TokenSvc as "TokenService"
participant Service as "AuthServiceImpl/AuthUserServiceImpl"
participant BaseEx as "GlobalExceptionHandlerAdvice"
participant Resp as "Result/PageResult"
Client->>Controller : "HTTP请求(含Token)"
Controller->>Filter : "进入安全过滤链"
Filter->>TokenSvc : "解析/校验Token"
TokenSvc-->>Filter : "用户上下文"
Filter-->>Controller : "放行或拒绝"
Controller->>Service : "调用业务逻辑"
Service-->>Controller : "返回业务结果"
Controller-->>Resp : "封装为统一响应"
Note over Controller,Resp : "正常路径"
Service-->>BaseEx : "抛出业务异常"
BaseEx-->>Resp : "统一错误响应"
Resp-->>Client : "HTTP响应"
```
图表来源
- [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java)
- [SystemController.java](file://crm-auth/src/main/java/com/crm/auth/controller/SystemController.java)
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
- [AuthServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java)
- [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java)
## 详细组件分析
### 认证与权限测试要点
- 单元测试
- 对TokenService进行Mock,验证Token生成、解析、过期判断分支
- 对AuthServiceImpl进行Mock,覆盖登录成功/失败、密码校验、第三方登录回调
- 对DingTalkAuthClient与ThirdPartyAuthClientFactory进行Mock,模拟第三方响应与异常
- 集成测试
- 使用SpringBootTest加载安全配置,构造JWT并发起请求,验证鉴权通过与否
- 使用@Sql或内存数据库初始化用户、角色、菜单数据,验证权限判定与数据范围
- 端到端测试
- 使用RestTemplate或WebTestClient发起登录、获取用户信息、受限资源访问等场景
- 断言HTTP状态码、统一响应结构与字段
```mermaid
classDiagram
class AuthController {
+登录()
+获取用户信息()
}
class JwtAuthenticationFilter {
+doFilter()
}
class TokenService {
+生成Token()
+解析Token()
+校验Token()
}
class AuthServiceImpl {
+登录()
+查询用户()
}
class DingTalkAuthClient {
+获取用户信息()
}
class ThirdPartyAuthClientFactory {
+创建客户端()
}
AuthController --> JwtAuthenticationFilter : "受保护"
JwtAuthenticationFilter --> TokenService : "解析/校验"
AuthController --> AuthServiceImpl : "调用"
AuthServiceImpl --> DingTalkAuthClient : "第三方登录"
AuthServiceImpl --> ThirdPartyAuthClientFactory : "选择客户端"
```
图表来源
- [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java)
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
- [AuthServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java)
- [DingTalkAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/DingTalkAuthClient.java)
- [ThirdPartyAuthClientFactory.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClientFactory.java)
章节来源
- [AuthServiceImplTest.java](file://crm-auth/src/test/java/com/crm/auth/service/impl/AuthServiceImplTest.java)
- [AuthUserServiceImplTest.java](file://crm-auth/src/test/java/com/crm/auth/service/impl/AuthUserServiceImplTest.java)
- [DingTalkAuthClientTest.java](file://crm-auth/src/test/java/com/crm/auth/service/client/DingTalkAuthClientTest.java)
- [ThirdPartyAuthClientFactoryTest.java](file://crm-auth/src/test/java/com/crm/auth/service/client/ThirdPartyAuthClientFactoryTest.java)
1 month ago
### 用户列表集成测试要点
**新增** 针对用户列表功能的全面集成测试,确保复杂查询场景的正确性
- 测试场景覆盖
- 用户列表分页查询:验证分页参数、排序规则、数据完整性
- 条件筛选测试:用户名、邮箱、状态等多条件组合查询
- 权限控制测试:不同角色用户的可见范围和数据隔离
- 性能测试:大数据量下的查询性能和响应时间
- 测试数据准备
- 使用@Sql脚本批量插入测试用户数据
- 模拟不同部门和角色的用户关系
- 准备边界条件和异常场景数据
- 断言策略
- 验证返回数据的结构和字段完整性
- 检查分页信息的准确性(总数、页码、每页大小)
- 确认权限控制生效,用户只能看到授权范围内的数据
```mermaid
flowchart TD
Start(["用户列表查询请求"]) --> ParseParams["解析查询参数"]
ParseParams --> ValidatePerm["验证用户权限"]
ValidatePerm --> BuildQuery["构建查询条件"]
BuildQuery --> ExecuteQuery["执行数据库查询"]
ExecuteQuery --> ApplyPagination["应用分页处理"]
ApplyPagination --> FormatResponse["格式化响应数据"]
FormatResponse --> Return["返回结果"]
```
图表来源
- [UserListIntegrationTest.java](file://crm-auth/src/test/java/com/crm/auth/service/impl/UserListIntegrationTest.java)
- [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java)
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
章节来源
- [UserListIntegrationTest.java](file://crm-auth/src/test/java/com/crm/auth/service/impl/UserListIntegrationTest.java)
1 month ago
### 数据权限与可见性测试要点
- 单元测试
- 对DataScopeHelper与DataVisibilityContext进行Mock,验证不同数据范围下的SQL拼接与上下文切换
- 对OwnedEntity与BaseEntity进行Mock,验证数据归属字段填充
- 集成测试
- 使用@DataScope注解与拦截器,构造不同用户与部门关系,验证查询结果集隔离
- 使用DataScopeIntegrationTest作为参考,结合测试实体与Mapper验证数据范围生效
1 month ago
- **扩展测试场景**:新增复杂的数据权限组合测试,包括多层级部门、跨部门数据共享等场景
1 month ago
- 端到端测试
- 以不同身份登录,访问同一接口,断言返回数据仅包含当前用户可访问范围
```mermaid
flowchart TD
Start(["进入受保护接口"]) --> CheckScope["读取数据权限上下文"]
CheckScope --> ScopeType{"数据范围类型"}
ScopeType --> |个人| BuildPersonal["拼接个人数据条件"]
ScopeType --> |部门| BuildDept["拼接部门数据条件"]
ScopeType --> |全部| NoFilter["不添加过滤条件"]
BuildPersonal --> Apply["应用到查询语句"]
BuildDept --> Apply
NoFilter --> Apply
Apply --> Execute["执行查询并返回结果"]
Execute --> End(["结束"])
```
图表来源
- [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java)
- [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java)
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
- [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java)
- [DataScopeIntegrationTest.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/DataScopeIntegrationTest.java)
- [TestOwnedData.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/TestOwnedData.java)
- [TestOwnedDataMapper.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/TestOwnedDataMapper.java)
章节来源
- [DataScopeIntegrationTest.java](file://crm-auth/src/test/java/com/crm/auth/security/scope/DataScopeIntegrationTest.java)
- [DataVisibilityTest.java](file://crm-base/src/test/java/com/crm/base/security/DataVisibilityTest.java)
### 文件服务测试要点
- 单元测试
- 对FileApiImpl与FileInfoServiceImpl进行Mock,验证上传会话创建、分片合并、元数据持久化
- 对KkFileViewClient进行Mock,模拟预览服务响应与超时/错误
- 对OrphanChunkCleanupTask进行Mock,验证分片清理逻辑与调度触发
- 集成测试
- 使用内存文件系统或Minio测试容器,验证真实上传下载流程
- 使用@Sql初始化文件记录,断言查询与删除行为
- 端到端测试
- 通过FileController上传大文件、断点续传、下载与预览,验证网络中断恢复与进度反馈
```mermaid
sequenceDiagram
participant Client as "客户端"
participant FileCtrl as "FileController"
participant FileSvc as "FileApiImpl/FileInfoServiceImpl"
participant Minio as "对象存储"
participant Preview as "KkFileViewClient"
Client->>FileCtrl : "POST 上传/分片上传"
FileCtrl->>FileSvc : "创建会话/保存分片"
FileSvc->>Minio : "写入分片"
FileSvc-->>FileCtrl : "返回会话ID"
Client->>FileCtrl : "POST 合并分片"
FileCtrl->>FileSvc : "合并并生成文件信息"
FileSvc->>Minio : "合并分片"
FileSvc-->>Client : "返回文件URL"
Client->>Preview : "GET 预览链接"
Preview-->>Client : "返回预览地址"
```
图表来源
- [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java)
- [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
章节来源
- [FileApiImplTest.java](file://crm-file/src/test/java/com/crm/file/service/impl/FileApiImplTest.java)
- [KkFileViewClientTest.java](file://crm-file/src/test/java/com/crm/file/service/KkFileViewClientTest.java)
- [OrphanChunkCleanupTaskTest.java](file://crm-file/src/test/java/com/crm/file/task/OrphanChunkCleanupTaskTest.java)
### 异常处理与统一响应测试要点
- 单元测试
- 对GlobalExceptionHandlerAdvice进行Mock,验证各业务异常映射到统一Result结构
- 对Result与ResultCodeEnum进行断言,确保错误码与消息一致性
- 集成测试
- 在控制器或服务中抛出MissingParameterException、PermissionErrorException、ResourceNotExistException等,验证全局异常处理器捕获并返回正确HTTP状态码
- 端到端测试
- 构造非法参数、越权访问、资源不存在等场景,断言响应体中的code、message、data字段
```mermaid
flowchart TD
Entry(["业务方法抛出异常"]) --> Catch["全局异常处理器捕获"]
Catch --> Classify{"异常类型分类"}
Classify --> |参数缺失| ParamErr["参数缺失错误"]
Classify --> |权限不足| PermErr["权限错误"]
Classify --> |资源不存在| ResErr["资源不存在错误"]
Classify --> |其他业务| BizErr["业务错误"]
ParamErr --> Wrap["封装为Result"]
PermErr --> Wrap
ResErr --> Wrap
BizErr --> Wrap
Wrap --> Return(["返回统一响应"])
```
图表来源
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java)
- [MissingParameterException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/MissingParameterException.java)
- [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java)
- [ResourceNotExistException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/ResourceNotExistException.java)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
章节来源
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
## 依赖关系分析
- 模块内依赖
- crm-auth依赖crm-base(异常、结果、安全上下文、实体基类)
- crm-file依赖crm-base(结果、实体基类)
- 外部依赖
- JWT与Spring Security用于认证与鉴权
- MyBatis-Plus用于数据访问
- 对象存储(如MinIO)用于文件存储
- 第三方登录(钉钉等)与预览服务(KKFileView)
```mermaid
graph LR
CRM_APP["crm-app"] --> CRM_AUTH["crm-auth"]
CRM_APP --> CRM_FILE["crm-file"]
CRM_AUTH --> CRM_BASE["crm-base"]
CRM_FILE --> CRM_BASE["crm-base"]
CRM_AUTH --> EXT_OAUTH["第三方登录(OAuth)"]
CRM_FILE --> EXT_STORE["对象存储(MinIO)"]
CRM_FILE --> EXT_PREVIEW["预览服务(KKFileView)"]
```
图表来源
- [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java)
- [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java)
- [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java)
章节来源
- [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java)
## 性能考虑
- 单元测试
- 避免I/O与网络调用,使用Mock减少耗时;对复杂算法进行边界值与大数据量输入测试
- 集成测试
- 使用内存数据库或测试容器缩短启动时间;合理设置事务回滚与数据隔离
- 对文件上传/下载进行流式处理与分片大小调优测试
1 month ago
- **新增** 对用户列表等复杂查询进行性能基准测试,监控SQL执行时间和数据库负载
1 month ago
- 端到端测试
- 使用轻量级客户端并发模拟,关注接口响应时间与吞吐
- 性能与压力测试
- 使用JMeter或Gatling进行压测,设计阶梯加压与长稳态场景
- 监控CPU、内存、GC、线程池、连接池与慢SQL
- 安全测试
- 使用OWASP ZAP或Burp Suite进行漏洞扫描与渗透测试
- 针对JWT伪造、越权、注入、XSS等进行专项用例
## 故障排查指南
- 常见问题定位
- 认证失败:检查JWT签名、过期时间、过滤器链顺序与白名单配置
- 权限不足:确认用户角色、菜单权限与数据范围上下文是否正确设置
- 文件上传失败:检查分片大小、存储桶权限、网络超时与重试策略
- 异常未捕获:确认全局异常处理器是否注册、异常类型是否匹配
1 month ago
- **新增** 用户列表查询问题:检查数据权限配置、SQL条件拼接、分页参数处理
1 month ago
- 调试建议
- 开启DEBUG日志,打印关键上下文(用户ID、角色、数据范围、请求ID)
- 使用Mock验证外部依赖行为,逐步缩小问题范围
- 使用集成测试复现问题,结合数据库快照与缓存状态对比
章节来源
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
## 结论
1 month ago
通过分层测试策略(单元、集成、端到端)、完善的Mock与测试数据管理、严格的覆盖率与持续集成规范,以及对认证、权限、文件、异常等核心能力的专项测试,可以显著提升代码质量与系统稳定性。新增的用户列表集成测试进一步增强了复杂业务场景的测试覆盖。建议将性能、压力与安全测试纳入常规流水线,形成闭环的质量保障体系。
1 month ago
## 附录
### 测试环境与数据准备
- 使用SpringBootTest加载最小化配置,启用内存数据库与Redis测试容器
- 使用@Sql或脚本初始化用户、角色、菜单、部门等基础数据
- 使用@DirtiesContext控制测试间上下文隔离,避免状态污染
1 month ago
- **新增** 用户列表测试数据准备:批量创建不同部门、角色的用户数据,模拟真实业务场景
1 month ago
章节来源
- [application.yml](file://crm-app/src/main/resources/application.yml)
### Mock策略与最佳实践
- 对外部依赖(第三方登录、对象存储、预览服务)一律Mock,保证测试快速稳定
- 对内部服务与方法使用@MockBean或构造器注入Mock,明确期望行为与返回值
- 对安全上下文与权限相关逻辑,使用测试辅助类或自定义注解简化设置
1 month ago
- **新增** 用户列表测试Mock策略:Mock数据库查询、权限验证、数据转换等依赖
1 month ago
章节来源
- [DingTalkAuthClientTest.java](file://crm-auth/src/test/java/com/crm/auth/service/client/DingTalkAuthClientTest.java)
- [ThirdPartyAuthClientFactoryTest.java](file://crm-auth/src/test/java/com/crm/auth/service/client/ThirdPartyAuthClientFactoryTest.java)
- [FileApiImplTest.java](file://crm-file/src/test/java/com/crm/file/service/impl/FileApiImplTest.java)
- [KkFileViewClientTest.java](file://crm-file/src/test/java/com/crm/file/service/KkFileViewClientTest.java)
### 测试覆盖率要求
- 行覆盖率≥80%,分支覆盖率≥70%,关键模块(认证、权限、文件)≥90%
- 使用JaCoCo生成报告,并在CI中阻断低覆盖率提交
1 month ago
- **新增** 用户列表功能覆盖率要求:查询逻辑、权限控制、分页处理等核心路径覆盖率≥95%
1 month ago
### 持续集成配置建议
- 在CI中执行mvn test与覆盖率聚合,失败则阻断流水线
- 并行执行单元测试与集成测试,缩短构建时间
- 生成测试报告与覆盖率HTML,归档至制品库
1 month ago
- **新增** 集成测试优化:使用测试容器加速数据库和Redis初始化
1 month ago
### 性能与压力测试工具推荐
- JMeter/Gatling:编写脚本模拟高并发登录、文件上传与下载
- Prometheus+Grafana:采集指标与可视化监控
- APM工具(SkyWalking/Arthas):链路追踪与线上诊断
1 month ago
- **新增** SQL性能分析:使用MyBatis-Plus的性能监控插件分析慢查询
1 month ago
### 安全测试方法与工具
- OWASP ZAP/Burp Suite:自动化漏洞扫描与手动渗透
- 依赖漏洞扫描(Dependabot/SonarQube):检测第三方库风险
- 敏感信息与密钥管理:使用环境变量与密钥管理服务
1 month ago
- **新增** 权限测试:验证水平越权、垂直越权、数据范围绕过等安全场景