docs: 添加测试报告和计划文档
- 添加E2E测试报告 - 添加UAT测试报告 - 添加测试计划文档 - 添加测试改进总结
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,370 @@
|
||||
# Novalon管理系统TDD改进方案实施计划
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** 通过测试驱动开发(TDD)方法全面提升Novalon管理系统的测试覆盖率、代码质量和系统可靠性
|
||||
|
||||
**Architecture:** 采用三阶段迭代改进方案,从基础设施修复到核心业务重构,再到前端优化,确保每个阶段都遵循"编写测试→实现功能→重构优化"的TDD流程
|
||||
|
||||
**Tech Stack:** Spring Boot 3.5.13, Vue 3, JUnit 5, Vitest, Playwright, pytest, PostgreSQL
|
||||
|
||||
---
|
||||
|
||||
## 项目现状分析
|
||||
|
||||
### 当前测试覆盖率
|
||||
- **API集成测试**: 26%覆盖率,存在编译错误
|
||||
- **后端单元测试**: 837个测试用例,18个测试失败
|
||||
- **前端单元测试**: 32个测试文件配置错误
|
||||
- **E2E测试**: Playwright配置问题导致无法运行
|
||||
|
||||
### 关键问题
|
||||
1. Java测试代码构造器参数不匹配
|
||||
2. Mock配置错误和依赖注入问题
|
||||
3. 异步测试断言不准确
|
||||
4. 前端测试环境配置错误
|
||||
|
||||
## 迭代计划概览
|
||||
|
||||
### 迭代周期1:基础设施修复与TDD流程建立(已完成)
|
||||
- ✅ 修复Java测试代码构造器参数问题
|
||||
- 🔄 建立TDD工作流规范
|
||||
|
||||
### 迭代周期2:核心业务逻辑TDD重构
|
||||
- 修复用户管理模块测试失败
|
||||
- 实现权限管理模块TDD开发
|
||||
- 提升API测试覆盖率至80%
|
||||
|
||||
### 迭代周期3:前端组件TDD优化
|
||||
- 修复前端测试配置问题
|
||||
- 实现Vue组件TDD开发模式
|
||||
- 完善E2E测试覆盖
|
||||
|
||||
## 详细实施任务
|
||||
|
||||
### 任务1:修复后端测试失败用例
|
||||
|
||||
**文件:**
|
||||
- Modify: `novalon-manage-api/manage-sys/src/test/java/cn/novalon/manage/sys/handler/auth/SysAuthHandlerTest.java`
|
||||
- Modify: `novalon-manage-api/manage-sys/src/test/java/cn/novalon/manage/sys/core/service/impl/SysUserServiceTest.java`
|
||||
- Modify: `novalon-manage-api/manage-sys/src/test/java/cn/novalon/manage/sys/interceptor/OperationLogFilterTest.java`
|
||||
|
||||
**步骤1:分析SysAuthHandlerTest测试失败原因**
|
||||
|
||||
```java
|
||||
// 检查第84行测试失败原因
|
||||
@Test
|
||||
void testLogin_Success() {
|
||||
// 分析expectNextMatches失败的具体原因
|
||||
}
|
||||
```
|
||||
|
||||
**步骤2:修复Mock配置问题**
|
||||
|
||||
```java
|
||||
// 确保所有Mock对象正确配置
|
||||
@Mock
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
when(passwordEncoder.matches(anyString(), anyString())).thenReturn(true);
|
||||
}
|
||||
```
|
||||
|
||||
**步骤3:修复异步测试断言**
|
||||
|
||||
```java
|
||||
// 使用正确的响应式测试模式
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(response -> {
|
||||
// 精确的断言逻辑
|
||||
return response.statusCode().is2xxSuccessful();
|
||||
})
|
||||
.verifyComplete();
|
||||
```
|
||||
|
||||
**步骤4:运行修复后的测试**
|
||||
|
||||
```bash
|
||||
cd /Users/zhangxiang/Codes/Novalon/novalon-manage-system/novalon-manage-api/manage-sys
|
||||
mvn test -Dtest=SysAuthHandlerTest
|
||||
```
|
||||
|
||||
**预期结果:** 所有SysAuthHandlerTest测试通过
|
||||
|
||||
### 任务2:修复前端测试配置
|
||||
|
||||
**文件:**
|
||||
- Modify: `novalon-manage-web/playwright.config.ts`
|
||||
- Modify: `novalon-manage-web/e2e/*.spec.ts`
|
||||
- Create: `novalon-manage-web/vitest.config.ts`
|
||||
|
||||
**步骤1:修复Playwright配置**
|
||||
|
||||
```typescript
|
||||
// playwright.config.ts
|
||||
import { defineConfig, devices } from '@playwright/test';
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './e2e',
|
||||
fullyParallel: true,
|
||||
forbidOnly: !!process.env.CI,
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
reporter: 'html',
|
||||
use: {
|
||||
baseURL: 'http://localhost:5173',
|
||||
trace: 'on-first-retry',
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
],
|
||||
webServer: {
|
||||
command: 'npm run dev',
|
||||
url: 'http://localhost:5173',
|
||||
reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
**步骤2:修复E2E测试文件**
|
||||
|
||||
```typescript
|
||||
// e2e/basic.spec.ts
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('basic test', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await expect(page).toHaveTitle(/Novalon/);
|
||||
});
|
||||
```
|
||||
|
||||
**步骤3:配置Vitest测试环境**
|
||||
|
||||
```typescript
|
||||
// vitest.config.ts
|
||||
import { defineConfig } from 'vitest/config';
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
test: {
|
||||
environment: 'jsdom',
|
||||
globals: true,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
**步骤4:运行前端测试**
|
||||
|
||||
```bash
|
||||
cd /Users/zhangxiang/Codes/Novalon/novalon-manage-system/novalon-manage-web
|
||||
npm run test:unit
|
||||
npm run test:e2e
|
||||
```
|
||||
|
||||
**预期结果:** 前端测试能够正常运行
|
||||
|
||||
### 任务3:实现用户管理模块TDD开发
|
||||
|
||||
**文件:**
|
||||
- Create: `novalon-manage-api/manage-sys/src/test/java/cn/novalon/manage/sys/core/service/impl/UserServiceTDDTest.java`
|
||||
- Modify: `novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysUserServiceImpl.java`
|
||||
|
||||
**步骤1:编写用户创建功能失败测试**
|
||||
|
||||
```java
|
||||
@Test
|
||||
void testCreateUser_WithInvalidEmail_ShouldFail() {
|
||||
CreateUserCommand command = new CreateUserCommand(
|
||||
"testuser",
|
||||
"password123",
|
||||
"invalid-email",
|
||||
"Test User"
|
||||
);
|
||||
|
||||
assertThrows(ValidationException.class, () -> {
|
||||
userService.createUser(command);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
**步骤2:运行测试确认失败**
|
||||
|
||||
```bash
|
||||
mvn test -Dtest=UserServiceTDDTest::testCreateUser_WithInvalidEmail_ShouldFail
|
||||
```
|
||||
|
||||
**步骤3:实现最小验证逻辑**
|
||||
|
||||
```java
|
||||
public Mono<SysUser> createUser(CreateUserCommand command) {
|
||||
// 添加邮箱格式验证
|
||||
if (!isValidEmail(command.getEmail())) {
|
||||
return Mono.error(new ValidationException("Invalid email format"));
|
||||
}
|
||||
|
||||
// 原有业务逻辑
|
||||
return userRepository.save(user);
|
||||
}
|
||||
|
||||
private boolean isValidEmail(String email) {
|
||||
return email.matches("^[A-Za-z0-9+_.-]+@(.+)$");
|
||||
}
|
||||
```
|
||||
|
||||
**步骤4:运行测试确认通过**
|
||||
|
||||
```bash
|
||||
mvn test -Dtest=UserServiceTDDTest::testCreateUser_WithInvalidEmail_ShouldFail
|
||||
```
|
||||
|
||||
**步骤5:提交代码**
|
||||
|
||||
```bash
|
||||
git add novalon-manage-api/manage-sys/src/test/java/cn/novalon/manage/sys/core/service/impl/UserServiceTDDTest.java
|
||||
git add novalon-manage-api/manage-sys/src/main/java/cn/novalon/manage/sys/core/service/impl/SysUserServiceImpl.java
|
||||
git commit -m "feat: add email validation with TDD approach"
|
||||
```
|
||||
|
||||
### 任务4:建立测试覆盖率监控
|
||||
|
||||
**文件:**
|
||||
- Create: `novalon-manage-system/.woodpecker/quality-gates.yml`
|
||||
- Modify: `novalon-manage-api/pom.xml`
|
||||
- Modify: `novalon-manage-web/package.json`
|
||||
|
||||
**步骤1:配置JaCoCo测试覆盖率**
|
||||
|
||||
```xml
|
||||
<!-- pom.xml -->
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.11</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>report</id>
|
||||
<phase>test</phase>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
```
|
||||
|
||||
**步骤2:配置质量门禁规则**
|
||||
|
||||
```yaml
|
||||
# .woodpecker/quality-gates.yml
|
||||
steps:
|
||||
- name: test-coverage-check
|
||||
image: maven:3.9-openjdk-21
|
||||
commands:
|
||||
- mvn clean test jacoco:report
|
||||
- |
|
||||
COVERAGE=$(cat target/site/jacoco/index.html | grep -oP 'Total.*?\K[0-9]+%' | head -1 | sed 's/%//')
|
||||
if [ $COVERAGE -lt 80 ]; then
|
||||
echo "Test coverage $COVERAGE% is below required 80%"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
**步骤3:配置前端测试覆盖率**
|
||||
|
||||
```json
|
||||
// package.json
|
||||
{
|
||||
"scripts": {
|
||||
"test:coverage": "vitest run --coverage",
|
||||
"test:e2e:coverage": "playwright test --reporter=html"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 任务5:建立TDD工作流规范
|
||||
|
||||
**文件:**
|
||||
- Create: `novalon-manage-system/docs/tdd-workflow.md`
|
||||
- Create: `novalon-manage-system/.github/workflows/tdd-pipeline.yml`
|
||||
|
||||
**步骤1:创建TDD工作流文档**
|
||||
|
||||
```markdown
|
||||
# TDD工作流规范
|
||||
|
||||
## 开发流程
|
||||
1. 编写失败测试用例(Red)
|
||||
2. 实现最小功能使测试通过(Green)
|
||||
3. 重构优化代码质量(Refactor)
|
||||
4. 提交代码并运行完整测试套件
|
||||
|
||||
## 质量门禁
|
||||
- 单元测试覆盖率 ≥ 80%
|
||||
- 集成测试覆盖率 ≥ 70%
|
||||
- 零编译错误,测试通过率100%
|
||||
```
|
||||
|
||||
**步骤2:配置GitHub Actions TDD流水线**
|
||||
|
||||
```yaml
|
||||
name: TDD Pipeline
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
tdd-validation:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '21'
|
||||
distribution: 'temurin'
|
||||
- name: Run TDD Tests
|
||||
run: |
|
||||
mvn clean test
|
||||
npm run test:coverage
|
||||
npm run test:e2e
|
||||
```
|
||||
|
||||
## 验收标准
|
||||
|
||||
### 质量指标
|
||||
- ✅ 后端单元测试覆盖率 ≥ 80%
|
||||
- ✅ 前端单元测试覆盖率 ≥ 70%
|
||||
- ✅ E2E测试关键路径覆盖率100%
|
||||
- ✅ 零编译错误,测试通过率100%
|
||||
|
||||
### 流程指标
|
||||
- ✅ TDD工作流规范文档完善
|
||||
- ✅ 质量门禁机制正常运行
|
||||
- ✅ 持续集成流水线稳定运行
|
||||
|
||||
## 风险与缓解措施
|
||||
|
||||
### 技术风险
|
||||
1. **异步测试复杂性** - 采用StepVerifier等专业工具
|
||||
2. **前端测试环境配置** - 使用容器化测试环境
|
||||
3. **测试数据管理** - 建立测试数据工厂模式
|
||||
|
||||
### 流程风险
|
||||
1. **团队TDD接受度** - 提供培训和最佳实践示例
|
||||
2. **测试维护成本** - 建立测试代码审查机制
|
||||
3. **性能影响** - 优化测试执行策略
|
||||
|
||||
---
|
||||
|
||||
**计划制定完成时间:** 2026-03-30
|
||||
**预计实施周期:** 2-3周
|
||||
**负责人:** 张翔(全栈质量保障与效能工程师)
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user