添加用户管理视图、API和状态管理文件
30 KiB
测试套件改进计划
For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: 将测试套件从当前77.8%覆盖率提升到金融级90%-95%标准,建立完整的测试金字塔,实现全生命周期质量保障
Architecture: 采用分层测试策略,优先补充高优先级覆盖率缺口,建立稳定可执行的测试基础设施,逐步引入性能、安全和集成测试
Tech Stack: Python (pytest, coverage), Playwright (TypeScript), Spring Boot (Java), Maven, Docker, CI/CD
改进阶段划分
阶段1: 高优先级修复(1-2周)- 覆盖率提升至85%+
阶段2: 中期优化(1-2个月)- 建立完整测试金字塔
阶段3: 长期建设(3-6个月)- 达到金融级合规标准
阶段1: 高优先级修复(1-2周)
Task 1: 补充main.py测试
Files:
- Create:
api/tests/unit/test_main.py - Test:
api/tests/unit/test_main.py
Step 1: 分析main.py功能
Read: api/src/apitest/main.py
Expected: 识别CLI入口点、参数解析、主流程
Step 2: Write failing tests
# api/tests/unit/test_main.py
import pytest
from unittest.mock import patch, MagicMock
from apitest.main import main
import sys
def test_main_with_no_arguments():
"""测试无参数时显示帮助信息"""
with patch('sys.argv', ['main']):
with patch('builtins.print') as mock_print:
main()
# 验证调用了print
assert mock_print.called
def test_main_with_valid_command():
"""测试有效命令执行"""
with patch('sys.argv', ['main', 'run', '--config', 'test.yaml']):
with patch('apitest.main.TestEngine') as mock_engine:
with patch('apitest.main.load_config') as mock_config:
mock_config.return_value = {'test': 'config'}
main()
# 验证创建了TestEngine
assert mock_engine.called
def test_main_with_invalid_command():
"""测试无效命令处理"""
with patch('sys.argv', ['main', 'invalid']):
with pytest.raises(SystemExit):
main()
def test_main_with_config_file_not_found():
"""测试配置文件不存在"""
with patch('sys.argv', ['main', 'run', '--config', 'nonexistent.yaml']):
with patch('builtins.open', side_effect=FileNotFoundError):
with pytest.raises(SystemExit):
main()
Step 3: Run test to verify it fails
Run: cd api && python -m pytest tests/unit/test_main.py -v
Expected: FAIL with "module 'apitest.main' not found" or import errors
Step 4: Implement minimal main.py structure
Read: api/src/apitest/main.py
If file is minimal, add basic structure:
# api/src/apitest/main.py
import sys
from apitest.cli_module import CLICommand
def main():
"""主入口函数"""
if len(sys.argv) < 2:
print("Usage: python -m apitest.main <command> [options]")
print("Commands: run, test, report")
sys.exit(1)
command = sys.argv[1]
cli = CLICommand()
if command == 'run':
cli.run_tests()
elif command == 'test':
cli.run_specific_test()
elif command == 'report':
cli.generate_report()
else:
print(f"Unknown command: {command}")
sys.exit(1)
if __name__ == '__main__':
main()
Step 5: Run test to verify it passes
Run: cd api && python -m pytest tests/unit/test_main.py -v
Expected: PASS
Step 6: Commit
git add api/tests/unit/test_main.py api/src/apitest/main.py
git commit -m "test: add main.py unit tests and basic CLI structure"
Task 2: 提升cli_module.py覆盖率到80%+
Files:
- Modify:
api/tests/unit/test_cli.py - Test:
api/tests/unit/test_cli.py
Step 1: 分析未覆盖代码行
Run: cd api && python -m pytest tests/unit/test_cli.py --cov=src/apitest/cli_module --cov-report=term-missing
Expected: 识别未覆盖的代码行(52, 61-93, 96-100, 131, 134-136, 158, 160, 162, 164, 167-170, 196-198, 223)
Step 2: Write tests for missing branches
# api/tests/unit/test_cli.py - 补充测试
def test_cli_run_with_invalid_config():
"""测试无效配置文件"""
cli = CLICommand()
with pytest.raises(Exception):
cli.run_tests(config='invalid.yaml')
def test_cli_run_with_missing_test_cases():
"""测试缺少测试用例"""
cli = CLICommand()
with patch('os.path.exists', return_value=False):
with pytest.raises(FileNotFoundError):
cli.run_tests()
def test_cli_report_generation():
"""测试报告生成功能"""
cli = CLICommand()
with patch('apitest.cli_module.ReportManager') as mock_report:
cli.generate_report()
assert mock_report.generate.called
def test_cli_error_handling():
"""测试错误处理逻辑"""
cli = CLICommand()
with patch.object(cli, 'run_tests', side_effect=Exception("Test error")):
with pytest.raises(Exception):
cli.run_tests()
Step 3: Run test to verify coverage improvement
Run: cd api && python -m pytest tests/unit/test_cli.py --cov=src/apitest/cli_module --cov-report=term-missing
Expected: Coverage increases from 72.6% to 80%+
Step 4: Commit
git add api/tests/unit/test_cli.py
git commit -m "test: improve cli_module.py coverage to 80%+"
Task 3: 修复API服务启动问题
Files:
- Modify:
everything-is-suitable-api/everything-is-suitable-app/src/main/resources/application.yml - Modify:
everything-is-suitable-api/everything-is-suitable-app/pom.xml - Test: Manual verification
Step 1: 分析bean冲突原因
Run: cd everything-is-suitable-api && mvn dependency:tree | grep jacksonConfig
Expected: 识别哪个模块定义了jacksonConfig bean
Step 2: 检查Spring Boot配置
Read: everything-is-suitable-api/everything-is-suitable-app/src/main/resources/application.yml
Look for bean configuration and component scanning
Step 3: 解决bean名称冲突
Option A: 重命名冲突的bean
// everything-is-suitable-api/everything-is-suitable-base/src/main/java/.../JacksonConfig.java
@Configuration
public class BaseJacksonConfig { // 重命名
// configuration
}
Option B: 使用@Primary注解
@Configuration
@Primary
public class AppJacksonConfig { // 标记为首选
// configuration
}
Step 4: 验证服务启动
Run: cd everything-is-suitable-api/everything-is-suitable-app && mvn spring-boot:run -Dspring-boot.run.profiles=dev
Expected: Service starts successfully on port 8080
Step 5: Commit
git add everything-is-suitable-api/
git commit -m "fix: resolve jacksonConfig bean name conflict"
Task 4: 修复E2E测试模块引用问题
Files:
- Modify:
e2e/examples/admin-role-management.spec.ts - Modify:
e2e/examples/admin-user-management.spec.ts - Test:
e2e/integration/login-mock.spec.ts
Step 1: 分析fixtures路径错误
Read: e2e/examples/admin-role-management.spec.ts:1
Expected: import { test, expect } from './fixtures/test-fixtures';
Step 2: 修复import路径
// e2e/examples/admin-role-management.spec.ts
// 修改为正确的相对路径
import { test, expect } from '../fixtures/test-fixtures';
Step 3: 验证所有测试文件
Run: cd e2e && grep -r "from './fixtures/test-fixtures'" examples/
Expected: 找到所有需要修复的文件
Step 4: 批量修复
Run: cd e2e && find examples/ -name "*.spec.ts" -exec sed -i '' "s|from './fixtures/test-fixtures'|from '../fixtures/test-fixtures'|g" {} \;
Step 5: 验证测试可执行
Run: cd e2e && ADMIN_BASE_URL=http://localhost:5173 npx playwright test examples/ --list
Expected: No module import errors
Step 6: Commit
git add e2e/examples/
git commit -m "fix: correct fixtures import paths in example tests"
Task 5: 建立测试环境管理脚本
Files:
- Create:
scripts/start-test-env.sh - Create:
scripts/stop-test-env.sh - Create:
scripts/check-services.sh
Step 1: 创建服务启动脚本
# scripts/start-test-env.sh
#!/bin/bash
set -e
echo "========================================="
echo " 启动测试环境"
echo "========================================"
# 检查端口占用
check_port() {
local port=$1
if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1; then
echo "端口 $port 已被占用"
return 1
fi
return 0
}
# 启动API服务
echo "----------------------------------------"
echo " 启动 API 服务..."
echo "----------------------------------------"
if check_port 8080; then
echo "API服务已在运行"
else
cd everything-is-suitable-api/everything-is-suitable-app
nohup mvn spring-boot:run -Dspring-boot.run.profiles=dev > /tmp/api.log 2>&1 &
echo "API服务启动中..."
sleep 30
fi
# 启动Admin服务
echo "----------------------------------------"
echo " 启动 Admin 服务..."
echo "----------------------------------------"
if check_port 5173; then
echo "Admin服务已在运行"
else
cd everything-is-suitable-admin
nohup npm run dev > /tmp/admin.log 2>&1 &
echo "Admin服务启动中..."
sleep 10
fi
# 验证服务健康
echo "----------------------------------------"
echo " 验证服务健康..."
echo "----------------------------------------"
bash scripts/check-services.sh
echo "========================================="
echo " ✅ 所有服务启动成功!"
echo "========================================="
Step 2: 创建服务停止脚本
# scripts/stop-test-env.sh
#!/bin/bash
set -e
echo "========================================="
echo " 停止测试环境"
echo "========================================"
# 停止API服务
echo "停止 API 服务..."
pkill -f "everything-is-suitable-app"
echo "API服务已停止"
# 停止Admin服务
echo "停止 Admin 服务..."
pkill -f "vite.*5173"
echo "Admin服务已停止"
echo "========================================="
echo " ✅ 所有服务已停止"
echo "========================================="
Step 3: 创建服务检查脚本
# scripts/check-services.sh
#!/bin/bash
set -e
echo "========================================="
echo " 服务状态检查"
echo "========================================="
# 检查API服务
echo "API 服务:"
if curl -s http://localhost:8080/api/health > /dev/null 2>&1; then
echo " ✅ 运行中 (http://localhost:8080/api/health)"
else
echo " ❌ 未运行"
fi
# 检查Admin服务
echo "Admin 服务:"
if curl -s http://localhost:5173 > /dev/null 2>&1; then
echo " ✅ 运行中 (http://localhost:5173)"
else
echo " ❌ 未运行"
fi
echo "========================================="
Step 4: 添加执行权限
Run: chmod +x scripts/start-test-env.sh scripts/stop-test-env.sh scripts/check-services.sh
Step 5: 测试脚本
Run: bash scripts/check-services.sh
Expected: 显示服务状态
Step 6: Commit
git add scripts/
git commit -m "feat: add test environment management scripts"
阶段2: 中期优化(1-2个月)
Task 6: 增加集成测试覆盖
Files:
- Create:
api/tests/integration/ - Create:
api/tests/integration/test_api_integration.py
Step 1: 设计集成测试场景
# api/tests/integration/test_api_integration.py
import pytest
import requests
from apitest.client.api_client import APIClient
from apitest.client.auth_manager import AuthManager
@pytest.fixture(scope="module")
def api_client():
"""API客户端fixture"""
return APIClient("http://localhost:8080")
@pytest.fixture(scope="module")
def auth_manager():
"""认证管理器fixture"""
return AuthManager(
"http://localhost:8080",
{"username": "admin", "password": "admin123"},
None
)
def test_api_integration_full_workflow(api_client, auth_manager):
"""测试完整API集成工作流"""
# 1. 登录
login_result = auth_manager.login()
assert login_result["data"]["token"]
# 2. 使用token访问受保护资源
api_client.set_auth_token(auth_manager._token)
result = api_client.get("/sys/user/list")
assert result["status_code"] == 200
# 3. 登出
auth_manager.logout()
assert auth_manager._token is None
Step 2: 创建集成测试配置
# api/tests/integration/conftest.py
import pytest
def pytest_configure(config):
"""集成测试配置"""
config.addinivalue_marker(
"integration",
"标记为集成测试,需要真实服务"
)
Step 3: 运行集成测试
Run: cd api && python -m pytest tests/integration/ -v -m integration
Expected: PASS (需要服务运行)
Step 4: Commit
git add api/tests/integration/
git commit -m "test: add API integration tests"
Task 7: 补充E2E业务流程测试
Files:
- Create:
e2e/integration/user-workflow.spec.ts - Create:
e2e/integration/role-workflow.spec.ts
Step 1: 设计用户管理工作流测试
// e2e/integration/user-workflow.spec.ts
import { test, expect } from '@playwright/test';
const BASE_URL = process.env.ADMIN_BASE_URL || 'http://localhost:5173';
test.describe('用户管理工作流E2E测试', () => {
test('完整用户生命周期', async ({ page }) => {
await page.goto(`${BASE_URL}/login`);
// 登录
await page.fill('[data-testid="username-input"]', 'admin');
await page.fill('[data-testid="password-input"]', 'admin123');
await page.click('[data-testid="login-button"]');
await expect(page).toHaveURL(/.*\//);
// 创建用户
await page.goto(`${BASE_URL}/system/user`);
await page.click('button:has-text("新增")');
await page.fill('[data-testid="username-input"]', 'testuser');
await page.fill('[data-testid="email-input"]', 'test@example.com');
await page.click('button:has-text("保存")');
await expect(page.locator('text=保存成功')).toBeVisible();
// 编辑用户
await page.click('td:has-text("testuser") button:has-text("编辑")');
await page.fill('[data-testid="email-input"]', 'updated@example.com');
await page.click('button:has-text("保存")');
await expect(page.locator('text=保存成功')).toBeVisible();
// 删除用户
await page.click('td:has-text("testuser") button:has-text("删除")');
await page.click('button:has-text("确认")');
await expect(page.locator('text=删除成功')).toBeVisible();
});
});
Step 2: 运行工作流测试
Run: cd e2e && ADMIN_BASE_URL=http://localhost:5173 npx playwright test integration/user-workflow.spec.ts --headed
Expected: PASS (需要完整服务)
Step 3: Commit
git add e2e/integration/
git commit -m "test: add user and role workflow E2E tests"
Task 8: 建立测试数据管理
Files:
- Create:
api/tests/factories/test_data_factory.py - Modify:
api/tests/conftest.py
Step 1: 创建测试数据工厂
# api/tests/factories/test_data_factory.py
from faker import Faker
fake = Faker('zh_CN')
class TestDataFactory:
"""测试数据工厂"""
@staticmethod
def create_user():
"""创建测试用户数据"""
return {
"username": fake.user_name(),
"email": fake.email(),
"phone": fake.phone_number(),
"password": fake.password(length=12),
}
@staticmethod
def create_role():
"""创建测试角色数据"""
return {
"roleName": fake.job(),
"description": fake.sentence(),
"permissions": ["user:read", "user:write"],
}
@staticmethod
def create_menu():
"""创建测试菜单数据"""
return {
"menuName": fake.word(),
"menuType": "directory",
"path": f"/{fake.word()}",
"icon": fake.word(),
}
Step 2: 集成到conftest
# api/tests/conftest.py
import pytest
from tests.factories.test_data_factory import TestDataFactory
@pytest.fixture
def test_user():
"""测试用户数据fixture"""
return TestDataFactory.create_user()
@pytest.fixture
def test_role():
"""测试角色数据fixture"""
return TestDataFactory.create_role()
Step 3: 使用测试数据工厂
# 在测试中使用
def test_create_user_with_factory(test_user):
"""使用工厂创建测试用户"""
result = api_client.post("/sys/user", body=test_user)
assert result["status_code"] == 201
Step 4: Commit
git add api/tests/factories/
git commit -m "feat: add test data factory for better test maintainability"
阶段3: 长期建设(3-6个月)
Task 9: 引入性能测试
Files:
- Create:
performance/load-test.jmx - Create:
performance/run-load-test.sh
Step 1: 创建JMeter负载测试计划
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2">
<hashTree>
<TestPlan guiclass="TestPlan" testclass="TestPlan" testname="API Load Test">
<elementProp name="TestPlan.user_define_classpath" elementType="TestPlan"
guiclass="TestPlan" testclass="TestPlan" testname="TestPlan.user_define_classpath">
<stringProp name="TestPlan.user_define_classpath" value=""/>
</elementProp>
<hashTree>
<ThreadGroup guiclass="ThreadGroup" testclass="ThreadGroup"
testname="Thread Group" sampler="LoopController">
<stringProp name="ThreadGroup.num_threads" value="100"/>
<stringProp name="ThreadGroup.ramp_time" value="10"/>
<stringProp name="ThreadGroup.duration" value="60"/>
<HTTPSamplerProxy guiclass="HTTPSamplerProxy" testclass="HTTPSamplerProxy"
testname="Login Request">
<stringProp name="HTTPSampler.domain" value="localhost"/>
<stringProp name="HTTPSampler.port" value="8080"/>
<stringProp name="HTTPSampler.path" value="/api/sys/auth/login"/>
<stringProp name="HTTPSampler.method" value="POST"/>
<elementProp name="HTTPsampler.Arguments" elementType="HTTPArguments">
<collectionProp name="HTTPsampler.Arguments.arguments">
<elementProp name="HTTPArgument" elementType="HTTPArgument">
<stringProp name="Argument.name" value="username"/>
<stringProp name="Argument.value" value="admin"/>
</elementProp>
<elementProp name="HTTPArgument" elementType="HTTPArgument">
<stringProp name="Argument.name" value="password"/>
<stringProp name="Argument.value" value="admin123"/>
</elementProp>
</collectionProp>
</elementProp>
</HTTPSamplerProxy>
</ThreadGroup>
</hashTree>
</hashTree>
</hashTree>
</jmeterTestPlan>
Step 2: 创建性能测试执行脚本
# performance/run-load-test.sh
#!/bin/bash
set -e
echo "========================================="
echo " 运行负载测试"
echo "========================================="
# 检查JMeter安装
if ! command -v jmeter &> /dev/null; then
echo "JMeter未安装,请先安装JMeter"
exit 1
fi
# 运行负载测试
jmeter -n -t performance/load-test.jmx \
-l performance/results.jtl \
-e -o performance/report \
-Jusers=100 \
-Jrampup=10 \
-Jduration=60
echo "========================================="
echo " 负载测试完成"
echo "========================================="
echo "报告位置: performance/report/index.html"
Step 3: Commit
git add performance/
git commit -m "feat: add performance testing with JMeter"
Task 10: 添加安全测试
Files:
- Create:
security/security-test.py - Create:
security/run-security-scan.sh
Step 1: 创建安全测试脚本
# security/security-test.py
import requests
import pytest
class TestSecurity:
"""安全测试套件"""
BASE_URL = "http://localhost:8080"
def test_sql_injection_protection(self):
"""测试SQL注入防护"""
malicious_payloads = [
"' OR '1'='1",
"admin'--",
"' UNION SELECT * FROM users--",
]
for payload in malicious_payloads:
response = requests.post(
f"{self.BASE_URL}/api/sys/auth/login",
json={"username": payload, "password": "test"}
)
# 应该返回401或400,而不是500
assert response.status_code in [400, 401]
def test_xss_protection(self):
"""测试XSS防护"""
xss_payloads = [
"<script>alert('xss')</script>",
"<img src=x onerror=alert('xss')>",
"javascript:alert('xss')",
]
for payload in xss_payloads:
response = requests.post(
f"{self.BASE_URL}/api/sys/user",
json={"username": payload}
)
# 应该过滤或转义
assert response.status_code in [400, 403]
def test_authentication_bypass(self):
"""测试认证绕过"""
# 测试无token访问
response = requests.get(f"{self.BASE_URL}/api/sys/user/list")
assert response.status_code == 401
# 测试过期token
response = requests.get(
f"{self.BASE_URL}/api/sys/user/list",
headers={"Authorization": "Bearer expired_token"}
)
assert response.status_code == 401
def test_sensitive_data_exposure(self):
"""测试敏感数据暴露"""
# 测试错误响应不应包含敏感信息
response = requests.post(
f"{self.BASE_URL}/api/sys/auth/login",
json={"username": "wrong", "password": "wrong"}
)
assert response.status_code == 401
# 验证不暴露数据库错误、堆栈信息等
assert "database" not in response.text.lower()
assert "stack" not in response.text.lower()
Step 2: 创建安全扫描脚本
# security/run-security-scan.sh
#!/bin/bash
set -e
echo "========================================="
echo " 运行安全扫描"
echo "========================================="
# 检查OWASP ZAP安装
if ! command -v zap-cli &> /dev/null; then
echo "OWASP ZAP未安装,请先安装ZAP"
exit 1
fi
# 运行ZAP扫描
zap-cli quick-scan \
-t http://localhost:5173 \
-r security/zap-report.html \
-x
echo "========================================="
echo " 安全扫描完成"
echo "========================================="
echo "报告位置: security/zap-report.html"
Step 3: Commit
git add security/
git commit -m "feat: add security testing suite"
Task 11: 实施AI辅助测试
Files:
- Create:
ai/test-generator.py - Create:
ai/defect-predictor.py
Step 1: 创建测试用例生成器
# ai/test-generator.py
import openai
from typing import List, Dict
class TestGenerator:
"""AI辅助测试用例生成器"""
def __init__(self, api_key: str):
self.client = openai.OpenAI(api_key=api_key)
def generate_test_cases(self, function_code: str) -> List[Dict]:
"""基于函数代码生成测试用例"""
prompt = f"""
基于以下函数代码,生成全面的测试用例:
{function_code}
要求:
1. 生成正常路径测试
2. 生成边界条件测试
3. 生成异常情况测试
4. 每个测试用例包含:测试名称、输入、预期输出
返回JSON格式的测试用例列表。
"""
response = self.client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}],
temperature=0.7
)
content = response.choices[0].message.content
return eval(content) # 简化,实际应使用JSON解析
def generate_test_code(self, test_case: Dict) -> str:
"""生成测试代码"""
prompt = f"""
基于以下测试用例,生成pytest测试代码:
测试名称: {test_case['name']}
输入: {test_case['input']}
预期输出: {test_case['expected']}
要求:
1. 使用pytest框架
2. 包含适当的断言
3. 添加必要的mock
"""
response = self.client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}],
temperature=0.3
)
return response.choices[0].message.content
Step 2: 创建缺陷预测器
# ai/defect-predictor.py
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd
class DefectPredictor:
"""基于历史数据的缺陷预测器"""
def __init__(self):
self.model = RandomForestClassifier(n_estimators=100)
self.vectorizer = TfidfVectorizer(max_features=1000)
def train(self, historical_data: pd.DataFrame):
"""训练模型"""
X = self.vectorizer.fit_transform(historical_data['code_changes'])
y = historical_data['has_defect']
self.model.fit(X, y)
def predict(self, code_changes: str) -> float:
"""预测缺陷概率"""
X = self.vectorizer.transform([code_changes])
probability = self.model.predict_proba(X)[0][1]
return probability
def get_risk_level(self, probability: float) -> str:
"""获取风险等级"""
if probability > 0.7:
return "高风险"
elif probability > 0.4:
return "中风险"
else:
return "低风险"
Step 3: Commit
git add ai/
git commit -m "feat: add AI-assisted testing tools"
Task 12: 建立CI/CD集成
Files:
- Create:
.github/workflows/test.yml - Create:
.github/workflows/quality-gate.yml
Step 1: 创建测试工作流
# .github/workflows/test.yml
name: Test Suite
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
api-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.13'
- name: Install dependencies
run: |
cd everything-is-suitable-test/api
pip install -r requirements.txt
- name: Run API tests
run: |
cd everything-is-suitable-test/api
python -m pytest tests/ --cov=src/apitest --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
files: ./everything-is-suitable-test/api/coverage.xml
- name: Check coverage threshold
run: |
coverage=$(python -c "import json; print(json.load(open('coverage.json'))['totals']['percent_covered'])")
if (( $(echo "$coverage < 85" | bc -l) )); then
echo "Coverage $coverage% is below threshold 85%"
exit 1
fi
e2e-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: |
cd everything-is-suitable-test/e2e
npm ci
- name: Install Playwright
run: npx playwright install --with-deps
- name: Run E2E tests
run: |
cd everything-is-suitable-test/e2e
npx playwright test
- name: Upload test results
uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: everything-is-suitable-test/e2e/playwright-report/
Step 2: 创建质量门禁工作流
# .github/workflows/quality-gate.yml
name: Quality Gate
on:
pull_request:
branches: [ main ]
jobs:
quality-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run linting
run: |
cd everything-is-suitable-test/api
flake8 src/apitest --max-line-length=100
- name: Run type checking
run: |
cd everything-is-suitable-test/api
mypy src/apitest --strict
- name: Check coverage
run: |
cd everything-is-suitable-test/api
python -m pytest tests/ --cov=src/apitest --cov-fail-under=85
- name: Security scan
run: |
bandit -r src/apitest -f json -o security-report.json
- name: Upload reports
uses: actions/upload-artifact@v3
with:
name: quality-reports
path: |
everything-is-suitable-test/api/security-report.json
Step 3: Commit
git add .github/workflows/
git commit -m "ci: add CI/CD pipelines with quality gates"
执行检查清单
阶段1完成标准
- main.py测试覆盖率 > 80%
- cli_module.py测试覆盖率 > 80%
- 整体API测试覆盖率 > 85%
- API服务可正常启动
- 所有E2E测试可执行
- 测试环境管理脚本可用
阶段2完成标准
- 集成测试覆盖核心业务流程
- E2E测试覆盖完整用户场景
- 测试数据工厂投入使用
- 测试类型分布均衡
阶段3完成标准
- 性能测试可执行
- 安全测试可执行
- AI辅助工具可用
- CI/CD流水线运行
- 质量门禁生效
- 整体覆盖率 > 90%
风险与缓解
风险1: API服务bean冲突
缓解: 优先解决Task 3,使用@Primary注解或重命名bean
风险2: E2E测试依赖后端
缓解: 使用Mock测试先行,真实后端测试作为补充
风险3: 性能测试环境要求
缓解: 使用轻量级负载测试,避免影响开发环境
风险4: AI工具成本
缓解: 使用开源模型或限制API调用次数
成功指标
阶段1指标
- 整体覆盖率: 77.8% → 85%+
- 测试通过率: 100% (保持)
- E2E可执行性: 8/87 → 87/87
阶段2指标
- 集成测试: 0 → 20+
- E2E业务流程: 8 → 30+
- 测试数据工厂: 0 → 1
阶段3指标
- 性能测试: 0 → 1个套件
- 安全测试: 0 → 1个套件
- AI辅助工具: 0 → 2个工具
- CI/CD: 0 → 2个流水线
- 整体覆盖率: 85% → 90%+
计划创建时间: 2026-03-07
计划创建人: 张翔(资深金融级高级自动化测试工程师)
预计完成时间: 6个月
执行方法: TDD + 频繁提交 + 持续验证