# 测试用例补充实施计划 > **目标**: 将API测试覆盖率从13%提升至80%以上,完善UAT测试覆盖,添加专项测试 **架构**: 基于现有测试框架,采用TDD方法,分层补充测试用例 **Tech Stack**: pytest (API测试), Playwright (E2E测试), TDD方法论 --- ## 优先级1: API测试补充(覆盖率提升至80%) ### Task 1: 补充用户管理API测试 **Files:** - Create: `api_integration_tests/tests/test_user_enhanced.py` - Modify: `api_integration_tests/api/user_api.py` **Step 1: 编写失败的测试 - 批量操作** ```python @pytest.mark.asyncio async def test_batch_create_users(self, authenticated_client, cleanup_user): """测试批量创建用户""" user_api = UserAPI(authenticated_client) users_data = [ { "username": f"batch_user_{i}_{int(time.time() * 1000)}", "password": "Test123!@#", "email": f"batch_{i}@example.com", "status": 1 } for i in range(5) ] results = [] for user_data in users_data: response = await user_api.create_user(user_data) assert response.status_code == 201 results.append(response.json()["id"]) cleanup_user.append(response.json()["id"]) assert len(results) == 5 ``` **Step 2: 运行测试验证失败** ```bash cd api_integration_tests pytest tests/test_user_enhanced.py::TestUserEnhanced::test_batch_create_users -v ``` Expected: FAIL - test_user_enhanced.py 文件不存在 **Step 3: 实现最小化代码** 创建文件 `api_integration_tests/tests/test_user_enhanced.py`: ```python """ 用户管理增强测试用例 """ import pytest import time from api.user_api import UserAPI @pytest.mark.user @pytest.mark.regression class TestUserEnhanced: """用户管理增强测试类""" @pytest.mark.asyncio async def test_batch_create_users(self, authenticated_client, cleanup_user): """测试批量创建用户""" user_api = UserAPI(authenticated_client) users_data = [ { "username": f"batch_user_{i}_{int(time.time() * 1000)}", "password": "Test123!@#", "email": f"batch_{i}@example.com", "status": 1 } for i in range(5) ] results = [] for user_data in users_data: response = await user_api.create_user(user_data) assert response.status_code == 201 results.append(response.json()["id"]) cleanup_user.append(response.json()["id"]) assert len(results) == 5 ``` **Step 4: 运行测试验证通过** ```bash cd api_integration_tests pytest tests/test_user_enhanced.py::TestUserEnhanced::test_batch_create_users -v ``` Expected: PASS **Step 5: 提交** ```bash git add api_integration_tests/tests/test_user_enhanced.py git commit -m "test: add batch create users test" ``` ### Task 2: 补充用户管理API测试 - 边界测试 **Files:** - Modify: `api_integration_tests/tests/test_user_enhanced.py` **Step 1: 编写失败的测试 - 超长用户名** ```python @pytest.mark.asyncio async def test_create_user_with_long_username(self, authenticated_client): """测试创建超长用户名""" user_api = UserAPI(authenticated_client) long_username = "a" * 100 # 超过限制长度 user_data = { "username": long_username, "password": "Test123!@#", "email": "test@example.com", "status": 1 } response = await user_api.create_user(user_data) assert response.status_code in [400, 422] ``` **Step 2: 运行测试验证失败** ```bash cd api_integration_tests pytest tests/test_user_enhanced.py::TestUserEnhanced::test_create_user_with_long_username -v ``` Expected: FAIL - 测试方法不存在 **Step 3: 实现最小化代码** 在 `test_user_enhanced.py` 中添加: ```python @pytest.mark.asyncio async def test_create_user_with_long_username(self, authenticated_client): """测试创建超长用户名""" user_api = UserAPI(authenticated_client) long_username = "a" * 100 user_data = { "username": long_username, "password": "Test123!@#", "email": "test@example.com", "status": 1 } response = await user_api.create_user(user_data) assert response.status_code in [400, 422] ``` **Step 4: 运行测试验证通过** ```bash cd api_integration_tests pytest tests/test_user_enhanced.py::TestUserEnhanced::test_create_user_with_long_username -v ``` Expected: PASS **Step 5: 提交** ```bash git add api_integration_tests/tests/test_user_enhanced.py git commit -m "test: add username length validation test" ``` ### Task 3: 补充用户管理API测试 - 无效邮箱格式 **Files:** - Modify: `api_integration_tests/tests/test_user_enhanced.py` **Step 1: 编写失败的测试** ```python @pytest.mark.asyncio async def test_create_user_with_invalid_email(self, authenticated_client): """测试创建无效邮箱格式""" user_api = UserAPI(authenticated_client) invalid_emails = [ "invalid", "@example.com", "test@", "test@.com", "test @example.com" ] for invalid_email in invalid_emails: user_data = { "username": f"test_{int(time.time() * 1000)}", "password": "Test123!@#", "email": invalid_email, "status": 1 } response = await user_api.create_user(user_data) assert response.status_code in [400, 422], f"Email {invalid_email} should be rejected" ``` **Step 2: 运行测试验证失败** ```bash cd api_integration_tests pytest tests/test_user_enhanced.py::TestUserEnhanced::test_create_user_with_invalid_email -v ``` Expected: FAIL - 测试方法不存在 **Step 3: 实现最小化代码** 在 `test_user_enhanced.py` 中添加: ```python @pytest.mark.asyncio async def test_create_user_with_invalid_email(self, authenticated_client): """测试创建无效邮箱格式""" user_api = UserAPI(authenticated_client) invalid_emails = [ "invalid", "@example.com", "test@", "test@.com", "test @example.com" ] for invalid_email in invalid_emails: user_data = { "username": f"test_{int(time.time() * 1000)}", "password": "Test123!@#", "email": invalid_email, "status": 1 } response = await user_api.create_user(user_data) assert response.status_code in [400, 422], f"Email {invalid_email} should be rejected" ``` **Step 4: 运行测试验证通过** ```bash cd api_integration_tests pytest tests/test_user_enhanced.py::TestUserEnhanced::test_create_user_with_invalid_email -v ``` Expected: PASS **Step 5: 提交** ```bash git add api_integration_tests/tests/test_user_enhanced.py git commit -m "test: add email format validation test" ``` ### Task 4: 补充角色管理API测试 - 权限分配 **Files:** - Create: `api_integration_tests/tests/test_role_enhanced.py` **Step 1: 编写失败的测试** ```python @pytest.mark.asyncio async def test_role_permission_assignment(self, authenticated_client, test_role_data, cleanup_role): """测试角色权限分配""" role_api = RoleAPI(authenticated_client) role_response = await role_api.create_role(test_role_data) role_id = role_response.json()["id"] cleanup_role.append(role_id) permissions = [ {"menuId": 1, "perms": "system:user:view"}, {"menuId": 2, "perms": "system:user:add"}, {"menuId": 3, "perms": "system:user:edit"} ] response = await role_api.assign_permissions(role_id, permissions) assert response.status_code == 200 verify_response = await role_api.get_role_by_id(role_id) role_data = verify_response.json() assert "permissions" in role_data or "menus" in role_data ``` **Step 2: 运行测试验证失败** ```bash cd api_integration_tests pytest tests/test_role_enhanced.py::TestRoleEnhanced::test_role_permission_assignment -v ``` Expected: FAIL - 文件不存在 **Step 3: 实现最小化代码** 创建文件 `api_integration_tests/tests/test_role_enhanced.py`: ```python """ 角色管理增强测试用例 """ import pytest import time from api.role_api import RoleAPI @pytest.mark.role @pytest.mark.regression class TestRoleEnhanced: """角色管理增强测试类""" @pytest.mark.asyncio async def test_role_permission_assignment(self, authenticated_client, test_role_data, cleanup_role): """测试角色权限分配""" role_api = RoleAPI(authenticated_client) role_response = await role_api.create_role(test_role_data) role_id = role_response.json()["id"] cleanup_role.append(role_id) permissions = [ {"menuId": 1, "perms": "system:user:view"}, {"menuId": 2, "perms": "system:user:add"}, {"menuId": 3, "perms": "system:user:edit"} ] response = await role_api.assign_permissions(role_id, permissions) assert response.status_code == 200 verify_response = await role_api.get_role_by_id(role_id) role_data = verify_response.json() assert "permissions" in role_data or "menus" in role_data ``` **Step 4: 运行测试验证通过** ```bash cd api_integration_tests pytest tests/test_role_enhanced.py::TestRoleEnhanced::test_role_permission_assignment -v ``` Expected: PASS **Step 5: 提交** ```bash git add api_integration_tests/tests/test_role_enhanced.py git commit -m "test: add role permission assignment test" ``` --- ## 优先级2: UAT测试补充 ### Task 5: 补充用户管理完整流程UAT测试 **Files:** - Create: `novalon-manage-web/e2e/uat-user-lifecycle.spec.ts` **Step 1: 编写失败的测试** ```typescript test('UAT-USER-001: 用户管理完整生命周期', async ({ page }) => { const loginPage = new LoginPage(page); const dashboardPage = new DashboardPage(page); const userManagementPage = new UserManagementPage(page); await test.step('1. 管理员登录', async () => { await loginPage.goto(); await loginPage.usernameInput.fill('admin'); await loginPage.passwordInput.fill('admin123'); await loginPage.loginButton.click(); await page.waitForURL(/.*dashboard/); }); await test.step('2. 创建新用户', async () => { await dashboardPage.navigateToUserManagement(); await userManagementPage.clickCreateUser(); const timestamp = Date.now(); const userData = { username: `uat_user_${timestamp}`, nickname: `UAT测试用户${timestamp}`, email: `uat_${timestamp}@example.com`, phone: '13800138000', password: 'Test123!@#', confirmPassword: 'Test123!@#', }; await userManagementPage.fillUserForm(userData); await userManagementPage.submitForm(); await expect(userManagementPage.successMessage).toBeVisible(); }); await test.step('3. 编辑用户信息', async () => { await userManagementPage.clickEditButton(1); const updatedNickname = `更新用户_${Date.now()}`; await userManagementPage.fillNickname(updatedNickname); await userManagementPage.submitForm(); await expect(userManagementPage.successMessage).toBeVisible(); }); await test.step('4. 删除用户', async () => { await userManagementPage.clickDeleteButton(1); await page.on('dialog', dialog => dialog.accept()); await expect(userManagementPage.successMessage).toBeVisible(); }); }); ``` **Step 2: 运行测试验证失败** ```bash cd novalon-manage-web npx playwright test uat-user-lifecycle.spec.ts --headed ``` Expected: FAIL - 文件不存在 **Step 3: 实现最小化代码** 创建文件 `novalon-manage-web/e2e/uat-user-lifecycle.spec.ts`: ```typescript import { test, expect } from '@playwright/test'; import { LoginPage } from './pages/LoginPage'; import { DashboardPage } from './pages/DashboardPage'; import { UserManagementPage } from './pages/UserManagementPage'; test.describe('UAT用户管理完整流程测试', () => { test('UAT-USER-001: 用户管理完整生命周期', async ({ page }) => { const loginPage = new LoginPage(page); const dashboardPage = new DashboardPage(page); const userManagementPage = new UserManagementPage(page); await test.step('1. 管理员登录', async () => { await loginPage.goto(); await loginPage.usernameInput.fill('admin'); await loginPage.passwordInput.fill('admin123'); await loginPage.loginButton.click(); await page.waitForURL(/.*dashboard/); }); await test.step('2. 创建新用户', async () => { await dashboardPage.navigateToUserManagement(); await userManagementPage.clickCreateUser(); const timestamp = Date.now(); const userData = { username: `uat_user_${timestamp}`, nickname: `UAT测试用户${timestamp}`, email: `uat_${timestamp}@example.com`, phone: '13800138000', password: 'Test123!@#', confirmPassword: 'Test123!@#', }; await userManagementPage.fillUserForm(userData); await userManagementPage.submitForm(); await expect(userManagementPage.successMessage).toBeVisible(); }); await test.step('3. 编辑用户信息', async () => { await userManagementPage.clickEditButton(1); const updatedNickname = `更新用户_${Date.now()}`; await userManagementPage.fillNickname(updatedNickname); await userManagementPage.submitForm(); await expect(userManagementPage.successMessage).toBeVisible(); }); await test.step('4. 删除用户', async () => { await userManagementPage.clickDeleteButton(1); await page.on('dialog', dialog => dialog.accept()); await expect(userManagementPage.successMessage).toBeVisible(); }); }); }); ``` **Step 4: 运行测试验证通过** ```bash cd novalon-manage-web npx playwright test uat-user-lifecycle.spec.ts --headed ``` Expected: PASS **Step 5: 提交** ```bash git add novalon-manage-web/e2e/uat-user-lifecycle.spec.ts git commit -m "test: add UAT user lifecycle test" ``` ### Task 6: 补充权限分配流程UAT测试 **Files:** - Create: `novalon-manage-web/e2e/uat-permission-workflow.spec.ts` **Step 1: 编写失败的测试** ```typescript test('UAT-PERM-001: 权限分配完整流程', async ({ page }) => { const loginPage = new LoginPage(page); const dashboardPage = new DashboardPage(page); const roleManagementPage = new RoleManagementPage(page); const userManagementPage = new UserManagementPage(page); await test.step('1. 管理员登录', async () => { await loginPage.goto(); await loginPage.login('admin', 'admin123'); await page.waitForURL(/.*dashboard/); }); await test.step('2. 创建新角色', async () => { await dashboardPage.navigateToRoleManagement(); await roleManagementPage.clickCreateRole(); const timestamp = Date.now(); const roleData = { roleName: `UAT角色_${timestamp}`, roleKey: `uat_role_${timestamp}`, roleSort: '1', status: '1', remark: 'UAT测试角色' }; await roleManagementPage.fillRoleForm(roleData); await roleManagementPage.submitForm(); await expect(roleManagementPage.successMessage).toBeVisible(); }); await test.step('3. 为角色分配权限', async () => { await roleManagementPage.openPermissionDialog(1); await roleManagementPage.selectPermission('system:user:view'); await roleManagementPage.selectPermission('system:user:add'); await roleManagementPage.submitPermissions(); await expect(roleManagementPage.successMessage).toBeVisible(); }); await test.step('4. 为用户分配角色', async () => { await dashboardPage.navigateToUserManagement(); await userManagementPage.clickEditButton(1); await userManagementPage.selectRole('UAT角色'); await userManagementPage.submitForm(); await expect(userManagementPage.successMessage).toBeVisible(); }); }); ``` **Step 2: 运行测试验证失败** ```bash cd novalon-manage-web npx playwright test uat-permission-workflow.spec.ts --headed ``` Expected: FAIL - 文件不存在 **Step 3: 实现最小化代码** 创建文件 `novalon-manage-web/e2e/uat-permission-workflow.spec.ts`: ```typescript import { test, expect } from '@playwright/test'; import { LoginPage } from './pages/LoginPage'; import { DashboardPage } from './pages/DashboardPage'; import { RoleManagementPage } from './pages/RoleManagementPage'; import { UserManagementPage } from './pages/UserManagementPage'; test.describe('UAT权限分配流程测试', () => { test('UAT-PERM-001: 权限分配完整流程', async ({ page }) => { const loginPage = new LoginPage(page); const dashboardPage = new DashboardPage(page); const roleManagementPage = new RoleManagementPage(page); const userManagementPage = new UserManagementPage(page); await test.step('1. 管理员登录', async () => { await loginPage.goto(); await loginPage.login('admin', 'admin123'); await page.waitForURL(/.*dashboard/); }); await test.step('2. 创建新角色', async () => { await dashboardPage.navigateToRoleManagement(); await roleManagementPage.clickCreateRole(); const timestamp = Date.now(); const roleData = { roleName: `UAT角色_${timestamp}`, roleKey: `uat_role_${timestamp}`, roleSort: '1', status: '1', remark: 'UAT测试角色' }; await roleManagementPage.fillRoleForm(roleData); await roleManagementPage.submitForm(); await expect(roleManagementPage.successMessage).toBeVisible(); }); await test.step('3. 为角色分配权限', async () => { await roleManagementPage.openPermissionDialog(1); await roleManagementPage.selectPermission('system:user:view'); await roleManagementPage.selectPermission('system:user:add'); await roleManagementPage.submitPermissions(); await expect(roleManagementPage.successMessage).toBeVisible(); }); await test.step('4. 为用户分配角色', async () => { await dashboardPage.navigateToUserManagement(); await userManagementPage.clickEditButton(1); await userManagementPage.selectRole('UAT角色'); await userManagementPage.submitForm(); await expect(userManagementPage.successMessage).toBeVisible(); }); }); }); ``` **Step 4: 运行测试验证通过** ```bash cd novalon-manage-web npx playwright test uat-permission-workflow.spec.ts --headed ``` Expected: PASS **Step 5: 提交** ```bash git add novalon-manage-web/e2e/uat-permission-workflow.spec.ts git commit -m "test: add UAT permission workflow test" ``` --- ## 优先级3: 跨浏览器测试 ### Task 7: 添加跨浏览器配置 **Files:** - Modify: `novalon-manage-web/playwright.config.ts` **Step 1: 编写失败的测试** 在 `playwright.config.ts` 中添加多浏览器配置: ```typescript export default defineConfig({ testDir: './e2e', timeout: 30000, expect: { timeout: 5000, }, fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 1 : undefined, reporter: [['html'], ['junit', { outputFile: 'results.xml' }]], use: { baseURL: 'http://localhost:3001', trace: 'on-first-retry', screenshot: 'only-on-failure', video: 'retain-on-failure', }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] } }, { name: 'firefox', use: { ...devices['Desktop Firefox'] } }, { name: 'webkit', use: { ...devices['Desktop Safari'] } }, { name: 'Mobile Chrome', use: { ...devices['Pixel 5'] } }, ], }); ``` **Step 2: 运行测试验证** ```bash cd novalon-manage-web npx playwright test --project=firefox ``` Expected: PASS - Firefox浏览器测试通过 **Step 3: 提交** ```bash git add novalon-manage-web/playwright.config.ts git commit -m "test: add cross-browser support" ``` --- ## 优先级4: 性能测试 ### Task 8: 添加API性能测试 **Files:** - Create: `api_integration_tests/tests/test_performance.py` **Step 1: 编写失败的测试** ```python @pytest.mark.performance @pytest.mark.asyncio async def test_api_response_time(self, authenticated_client): """测试API响应时间""" user_api = UserAPI(authenticated_client) start_time = time.time() response = await user_api.get_all_users() end_time = time.time() response_time = (end_time - start_time) * 1000 # 转换为毫秒 assert response.status_code == 200 assert response_time < 1000, f"API响应时间 {response_time}ms 超过1000ms阈值" ``` **Step 2: 运行测试验证失败** ```bash cd api_integration_tests pytest tests/test_performance.py::TestPerformance::test_api_response_time -v ``` Expected: FAIL - 文件不存在 **Step 3: 实现最小化代码** 创建文件 `api_integration_tests/tests/test_performance.py`: ```python """ 性能测试用例 """ import pytest import time import asyncio from api.user_api import UserAPI from api.role_api import RoleAPI @pytest.mark.performance class TestPerformance: """性能测试类""" @pytest.mark.asyncio async def test_api_response_time(self, authenticated_client): """测试API响应时间""" user_api = UserAPI(authenticated_client) start_time = time.time() response = await user_api.get_all_users() end_time = time.time() response_time = (end_time - start_time) * 1000 assert response.status_code == 200 assert response_time < 1000, f"API响应时间 {response_time}ms 超过1000ms阈值" @pytest.mark.asyncio async def test_concurrent_requests(self, authenticated_client): """测试并发请求性能""" user_api = UserAPI(authenticated_client) async def make_request(): return await user_api.get_all_users() start_time = time.time() tasks = [make_request() for _ in range(10)] responses = await asyncio.gather(*tasks) end_time = time.time() total_time = (end_time - start_time) * 1000 avg_time = total_time / 10 assert all(r.status_code == 200 for r in responses) assert avg_time < 500, f"平均响应时间 {avg_time}ms 超过500ms阈值" ``` **Step 4: 运行测试验证通过** ```bash cd api_integration_tests pytest tests/test_performance.py::TestPerformance::test_api_response_time -v ``` Expected: PASS **Step 5: 提交** ```bash git add api_integration_tests/tests/test_performance.py git commit -m "test: add API performance tests" ``` --- ## 优先级5: 安全测试 ### Task 9: 补充SQL注入测试 **Files:** - Modify: `api_integration_tests/tests/test_security.py` **Step 1: 编写失败的测试** ```python @pytest.mark.security @pytest.mark.asyncio async def test_sql_injection_prevention(self, authenticated_client): """测试SQL注入防护""" user_api = UserAPI(authenticated_client) sql_injection_payloads = [ "admin' OR '1'='1", "admin'; DROP TABLE users--", "admin' UNION SELECT * FROM users--", "1' AND 1=1--" ] for payload in sql_injection_payloads: user_data = { "username": payload, "password": "Test123!@#", "email": f"{payload}@example.com", "status": 1 } response = await user_api.create_user(user_data) assert response.status_code in [400, 422, 403], f"SQL注入payload {payload} 应该被拒绝" ``` **Step 2: 运行测试验证失败** ```bash cd api_integration_tests pytest tests/test_security.py::TestSecurity::test_sql_injection_prevention -v ``` Expected: FAIL - 测试方法不存在 **Step 3: 实现最小化代码** 在 `test_security.py` 中添加: ```python @pytest.mark.security @pytest.mark.asyncio async def test_sql_injection_prevention(self, authenticated_client): """测试SQL注入防护""" user_api = UserAPI(authenticated_client) sql_injection_payloads = [ "admin' OR '1'='1", "admin'; DROP TABLE users--", "admin' UNION SELECT * FROM users--", "1' AND 1=1--" ] for payload in sql_injection_payloads: user_data = { "username": payload, "password": "Test123!@#", "email": f"{payload}@example.com", "status": 1 } response = await user_api.create_user(user_data) assert response.status_code in [400, 422, 403], f"SQL注入payload {payload} 应该被拒绝" ``` **Step 4: 运行测试验证通过** ```bash cd api_integration_tests pytest tests/test_security.py::TestSecurity::test_sql_injection_prevention -v ``` Expected: PASS **Step 5: 提交** ```bash git add api_integration_tests/tests/test_security.py git commit -m "test: add SQL injection prevention test" ``` ### Task 10: 补充XSS攻击测试 **Files:** - Modify: `api_integration_tests/tests/test_security.py` **Step 1: 编写失败的测试** ```python @pytest.mark.security @pytest.mark.asyncio async def test_xss_prevention(self, authenticated_client): """测试XSS攻击防护""" user_api = UserAPI(authenticated_client) xss_payloads = [ "", "", "", "javascript:alert('XSS')", "" ] for payload in xss_payloads: user_data = { "username": f"test_{int(time.time() * 1000)}", "password": "Test123!@#", "email": "test@example.com", "nickname": payload } response = await user_api.create_user(user_data) if response.status_code == 201: user_id = response.json()["id"] get_response = await user_api.get_user_by_id(user_id) user_info = get_response.json() assert "", "", "", "javascript:alert('XSS')", "" ] for payload in xss_payloads: user_data = { "username": f"test_{int(time.time() * 1000)}", "password": "Test123!@#", "email": "test@example.com", "nickname": payload } response = await user_api.create_user(user_data) if response.status_code == 201: user_id = response.json()["id"] get_response = await user_api.get_user_by_id(user_id) user_info = get_response.json() assert "