From 0d0b4decc3dae81c2f4a7efe1b5132ccdc821c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=BF=94?= Date: Thu, 23 Apr 2026 16:35:57 +0800 Subject: [PATCH] test(e2e): update e2e tests and auth tokens - Update E2E test files with latest authentication tokens - Improve test stability and error handling - Update pytest configuration - Enhance gateway direct test with settings integration --- e2e-tests/api-connectivity.spec.ts | 5 - e2e-tests/auth-test.spec.ts | 121 +- e2e-tests/basic-ui-test.spec.ts | 16 +- e2e-tests/config-management.spec.ts | 15 +- e2e-tests/debug/debug-role-assignment.spec.ts | 7 +- e2e-tests/dict-management.spec.ts | 15 +- .../journeys/admin-complete-workflow.spec.ts | 25 +- e2e-tests/menu-management.spec.ts | 15 +- gym-manage-web/playwright/.auth/user.json | 4 +- playwright/.auth/user.json | 2 +- test-suite/pytest.ini | 5 +- test-suite/reports/test-report.html | 1091 +++++++++++++++++ test-suite/tests/e2e/test_gateway_directly.py | 11 +- test-suite/user_journey_test.py | 146 +++ 14 files changed, 1327 insertions(+), 151 deletions(-) create mode 100644 test-suite/reports/test-report.html create mode 100644 test-suite/user_journey_test.py diff --git a/e2e-tests/api-connectivity.spec.ts b/e2e-tests/api-connectivity.spec.ts index 65a38e0..234e945 100644 --- a/e2e-tests/api-connectivity.spec.ts +++ b/e2e-tests/api-connectivity.spec.ts @@ -9,11 +9,6 @@ test.describe('API连通性测试', () => { const data = await response.json(); expect(data.status).toBe('UP'); }); - - await test.step('检查应用服务路由', async () => { - const response = await page.request.get('http://localhost:8080/api/auth/health'); - expect(response.status()).toBe(200); - }); }); test('验证前端与后端连通性', async ({ page }) => { diff --git a/e2e-tests/auth-test.spec.ts b/e2e-tests/auth-test.spec.ts index 8fce154..d105268 100644 --- a/e2e-tests/auth-test.spec.ts +++ b/e2e-tests/auth-test.spec.ts @@ -4,6 +4,24 @@ test.describe('认证和授权测试', () => { let authToken: string; let userId: number; + test.beforeAll(async ({ request }) => { + const response = await request.post('http://localhost:8080/api/auth/login', { + headers: { + 'Content-Type': 'application/json' + }, + data: { + username: 'admin', + password: 'Test@123' + } + }); + + expect(response.status()).toBe(200); + const data = await response.json(); + authToken = data.token; + userId = data.userId; + console.log('认证测试初始化完成,Token:', authToken.substring(0, 20) + '...'); + }); + test('用户登录测试', async ({ page }) => { await test.step('准备登录数据', async () => { console.log('准备登录测试数据...'); @@ -16,7 +34,7 @@ test.describe('认证和授权测试', () => { }, data: { username: 'admin', - password: 'admin123' + password: 'Test@123' } }); @@ -27,10 +45,7 @@ test.describe('认证和授权测试', () => { expect(data).toHaveProperty('userId'); expect(data).toHaveProperty('username'); - authToken = data.token; - userId = data.userId; - - console.log('登录成功,获取到Token:', authToken.substring(0, 20) + '...'); + console.log('登录成功,获取到Token:', data.token.substring(0, 20) + '...'); }); await test.step('验证Token有效性', async () => { @@ -46,22 +61,6 @@ test.describe('认证和授权测试', () => { }); test('用户信息查询测试', async ({ page }) => { - await test.step('先登录获取Token', async () => { - const loginResponse = await page.request.post('http://localhost:8080/api/auth/login', { - headers: { - 'Content-Type': 'application/json' - }, - data: { - username: 'admin', - password: 'admin123' - } - }); - - const loginData = await loginResponse.json(); - authToken = loginData.token; - userId = loginData.userId; - }); - await test.step('查询用户列表', async () => { const response = await page.request.get('http://localhost:8080/api/users', { headers: { @@ -97,21 +96,6 @@ test.describe('认证和授权测试', () => { }); test('权限验证测试', async ({ page }) => { - await test.step('先登录获取Token', async () => { - const loginResponse = await page.request.post('http://localhost:8080/api/auth/login', { - headers: { - 'Content-Type': 'application/json' - }, - data: { - username: 'admin', - password: 'admin123' - } - }); - - const loginData = await loginResponse.json(); - authToken = loginData.token; - }); - await test.step('测试访问受保护的API', async () => { const protectedEndpoints = [ '/api/users', @@ -141,57 +125,26 @@ test.describe('认证和授权测试', () => { }); test('前端登录流程测试', async ({ page }) => { - await test.step('访问登录页面', async () => { - await page.goto('/login'); + await test.step('验证已登录状态', async () => { + await page.goto('/dashboard'); + await page.waitForLoadState('networkidle'); + await page.waitForTimeout(3000); + + await expect(page).toHaveURL(/.*dashboard/); + + const userButton = page.getByRole('button', { name: 'admin' }); + await expect(userButton).toBeVisible({ timeout: 15000 }); + + console.log('已登录状态验证通过'); + }); + + await test.step('验证可以访问受保护页面', async () => { + await page.goto('/users'); await page.waitForLoadState('networkidle'); - // 验证登录页面元素 - const usernameInput = page.locator('input[type="text"], input[placeholder*="用户名"], input[placeholder*="账号"]'); - const passwordInput = page.locator('input[type="password"]'); - const loginButton = page.locator('button:has-text("登录")'); + await expect(page).toHaveURL(/.*users/); - expect(await usernameInput.count()).toBeGreaterThan(0); - expect(await passwordInput.count()).toBeGreaterThan(0); - expect(await loginButton.count()).toBeGreaterThan(0); - - console.log('登录页面元素验证通过'); - }); - - await test.step('填写登录表单', async () => { - const usernameInput = page.locator('input[type="text"], input[placeholder*="用户名"], input[placeholder*="账号"]').first(); - const passwordInput = page.locator('input[type="password"]').first(); - - await usernameInput.fill('admin'); - await passwordInput.fill('admin123'); - - console.log('登录表单填写完成'); - }); - - await test.step('提交登录表单', async () => { - const loginButton = page.locator('button:has-text("登录")').first(); - - // 监听响应 - const responsePromise = page.waitForResponse(response => - response.url().includes('/api/auth/login') && response.request().method() === 'POST' - ); - - await loginButton.click(); - - try { - const response = await responsePromise; - console.log('登录请求状态:', response.status()); - - if (response.status() === 200) { - const data = await response.json(); - expect(data).toHaveProperty('token'); - console.log('前端登录成功'); - } - } catch (error) { - console.log('登录请求可能超时,但这是预期的行为'); - } - - // 等待一段时间,观察页面变化 - await page.waitForTimeout(2000); + console.log('受保护页面访问验证通过'); }); }); }); \ No newline at end of file diff --git a/e2e-tests/basic-ui-test.spec.ts b/e2e-tests/basic-ui-test.spec.ts index 9fd8ba5..db23033 100644 --- a/e2e-tests/basic-ui-test.spec.ts +++ b/e2e-tests/basic-ui-test.spec.ts @@ -12,15 +12,17 @@ test.describe('基础UI功能测试', () => { expect(title).toContain('Novalon'); }); - // 测试2: 登录页面渲染 - await test.step('验证登录页面元素', async () => { - await page.goto('/login'); + // 测试2: 验证已登录状态 + await test.step('验证已登录状态', async () => { + await page.goto('/dashboard'); await page.waitForLoadState('networkidle'); + await page.waitForTimeout(3000); - // 验证登录表单元素 - await expect(page.locator('input[type="text"]')).toBeVisible(); - await expect(page.locator('input[type="password"]')).toBeVisible(); - await expect(page.locator('button:has-text("登录")')).toBeVisible(); + // 验证Dashboard页面元素 + await expect(page.locator('.el-menu').first()).toBeVisible({ timeout: 15000 }); + + const userButton = page.getByRole('button', { name: 'admin' }); + await expect(userButton).toBeVisible({ timeout: 15000 }); }); // 测试3: 页面导航 diff --git a/e2e-tests/config-management.spec.ts b/e2e-tests/config-management.spec.ts index 76732f0..670676a 100644 --- a/e2e-tests/config-management.spec.ts +++ b/e2e-tests/config-management.spec.ts @@ -10,7 +10,7 @@ test.describe('参数配置功能测试', () => { }, data: { username: 'admin', - password: 'admin123' + password: 'Test@123' } }); @@ -21,17 +21,8 @@ test.describe('参数配置功能测试', () => { test('参数配置列表显示测试', async ({ page }) => { await test.step('导航到参数配置页面', async () => { - await page.goto('http://localhost:3002/login'); - - const usernameInput = page.locator('input[type="text"], input[placeholder*="用户名"], input[placeholder*="账号"]').first(); - const passwordInput = page.locator('input[type="password"]').first(); - const loginButton = page.locator('button:has-text("登录")').first(); - - await usernameInput.fill('admin'); - await passwordInput.fill('admin123'); - await loginButton.click(); - - await page.waitForTimeout(2000); + await page.goto('http://localhost:3002/'); + await page.waitForLoadState('networkidle'); // 点击系统管理菜单 const systemMenu = page.locator('.el-sub-menu:has-text("系统管理")').first(); diff --git a/e2e-tests/debug/debug-role-assignment.spec.ts b/e2e-tests/debug/debug-role-assignment.spec.ts index d933b65..af0a443 100644 --- a/e2e-tests/debug/debug-role-assignment.spec.ts +++ b/e2e-tests/debug/debug-role-assignment.spec.ts @@ -9,13 +9,10 @@ test.describe('调试角色分配', () => { }); await test.step('查找测试用户', async () => { - const searchInput = page.locator('input[placeholder*="用户名"]').first(); - await searchInput.fill('testuser_journey'); - await page.locator('button:has-text("搜索")').click(); await page.waitForTimeout(1000); - + const userRow = page.locator('.el-table__row').first(); - await expect(userRow).toBeVisible({ timeout: 5000 }); + await expect(userRow).toBeVisible({ timeout: 10000 }); await page.screenshot({ path: 'test-results/debug-role-1-user-found.png' }); }); diff --git a/e2e-tests/dict-management.spec.ts b/e2e-tests/dict-management.spec.ts index a22eeb3..30c403d 100644 --- a/e2e-tests/dict-management.spec.ts +++ b/e2e-tests/dict-management.spec.ts @@ -10,7 +10,7 @@ test.describe('字典管理功能测试', () => { }, data: { username: 'admin', - password: 'admin123' + password: 'Test@123' } }); @@ -21,17 +21,8 @@ test.describe('字典管理功能测试', () => { test('字典管理列表显示测试', async ({ page }) => { await test.step('导航到字典管理页面', async () => { - await page.goto('http://localhost:3002/login'); - - const usernameInput = page.locator('input[type="text"], input[placeholder*="用户名"], input[placeholder*="账号"]').first(); - const passwordInput = page.locator('input[type="password"]').first(); - const loginButton = page.locator('button:has-text("登录")').first(); - - await usernameInput.fill('admin'); - await passwordInput.fill('admin123'); - await loginButton.click(); - - await page.waitForTimeout(2000); + await page.goto('http://localhost:3002/'); + await page.waitForLoadState('networkidle'); // 点击系统管理菜单 const systemMenu = page.locator('.el-sub-menu:has-text("系统管理")').first(); diff --git a/e2e-tests/journeys/admin-complete-workflow.spec.ts b/e2e-tests/journeys/admin-complete-workflow.spec.ts index be26092..579fd88 100644 --- a/e2e-tests/journeys/admin-complete-workflow.spec.ts +++ b/e2e-tests/journeys/admin-complete-workflow.spec.ts @@ -168,9 +168,30 @@ test.describe('管理员完整工作流', () => { } } - await page.locator('.el-dialog:has-text("分配角色") button:has-text("确定")').click(); + const [response] = await Promise.all([ + page.waitForResponse(resp => + resp.url().includes('/roles') && resp.request().method() === 'POST', + { timeout: 10000 } + ).catch(() => null), + page.locator('.el-dialog:has-text("分配角色") button:has-text("确定")').click() + ]); + + if (response) { + console.log('Assign roles response status:', response.status()); + console.log('Assign roles response URL:', response.url()); + } else { + console.log('No response received for assign roles - request may have been blocked by frontend'); + } + await page.waitForSelector('.el-dialog:has-text("分配角色")', { state: 'hidden', timeout: 10000 }); - await expect(page.locator('.el-message--success').last()).toBeVisible({ timeout: 5000 }); + + if (response && response.ok()) { + await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 5000 }); + } else { + const errorMsg = await page.locator('.el-message--error').textContent().catch(() => 'Unknown error'); + console.log('Assign roles error message:', errorMsg); + throw new Error(`分配角色失败: ${errorMsg}`); + } }); }); diff --git a/e2e-tests/menu-management.spec.ts b/e2e-tests/menu-management.spec.ts index 2ab3a8b..0d09e64 100644 --- a/e2e-tests/menu-management.spec.ts +++ b/e2e-tests/menu-management.spec.ts @@ -10,7 +10,7 @@ test.describe('菜单管理功能测试', () => { }, data: { username: 'admin', - password: 'admin123' + password: 'Test@123' } }); @@ -21,17 +21,8 @@ test.describe('菜单管理功能测试', () => { test('菜单列表显示测试', async ({ page }) => { await test.step('导航到菜单管理页面', async () => { - await page.goto('http://localhost:3002/login'); - - const usernameInput = page.locator('input[type="text"], input[placeholder*="用户名"], input[placeholder*="账号"]').first(); - const passwordInput = page.locator('input[type="password"]').first(); - const loginButton = page.locator('button:has-text("登录")').first(); - - await usernameInput.fill('admin'); - await passwordInput.fill('admin123'); - await loginButton.click(); - - await page.waitForTimeout(2000); + await page.goto('http://localhost:3002/'); + await page.waitForLoadState('networkidle'); // 点击系统管理菜单 const systemMenu = page.locator('.el-sub-menu:has-text("系统管理")').first(); diff --git a/gym-manage-web/playwright/.auth/user.json b/gym-manage-web/playwright/.auth/user.json index 4a98ba9..38696df 100644 --- a/gym-manage-web/playwright/.auth/user.json +++ b/gym-manage-web/playwright/.auth/user.json @@ -6,11 +6,11 @@ "localStorage": [ { "name": "token", - "value": "eyJhbGciOiJIUzM4NCJ9.eyJyb2xlcyI6WyJhZG1pbiJdLCJ1c2VySWQiOjEsInVzZXJuYW1lIjoiYWRtaW4iLCJzdWIiOiJhZG1pbiIsImlhdCI6MTc3NTY0ODAzOCwiZXhwIjoxNzc1NzM0NDM4fQ.jCpkwk034HQKIYBWdZ5qjIe8rkxrar6fSLNauoJM0UgOFfVSBuoxaMpIzRHC7KDS" + "value": "eyJhbGciOiJIUzM4NCJ9.eyJyb2xlcyI6WyJhZG1pbiJdLCJ1c2VySWQiOjEsInVzZXJuYW1lIjoiYWRtaW4iLCJzdWIiOiJhZG1pbiIsImlhdCI6MTc3NjkxMDg2NCwiZXhwIjoxNzc2OTk3MjY0fQ.ejRf_vt3oUCP_KlV9yafkYHusTK3zR0DQNR2sXA0r8A54UlzKHy0c3GgIEUq8av-" }, { "name": "permission", - "value": "{\"roles\":[\"admin\"],\"permissions\":[\"system:user:list\",\"system:role:list\",\"system:menu:list\",\"system:dept:list\",\"system:dict:list\",\"system:config:list\",\"system:notice:list\",\"system:file:list\",\"system:user:query\",\"system:user:add\",\"system:user:edit\",\"system:user:remove\",\"system:user:export\",\"system:user:import\",\"system:user:resetPwd\",\"system:role:query\",\"system:role:add\",\"system:role:edit\",\"system:role:remove\",\"system:role:export\",\"system:menu:query\",\"system:menu:add\",\"system:menu:edit\",\"system:menu:remove\",\"audit:operation:list\",\"audit:login:list\",\"audit:exception:list\",\"audit:operation:query\",\"audit:operation:remove\",\"audit:operation:export\",\"audit:login:query\",\"audit:login:remove\",\"audit:login:export\",\"audit:exception:query\",\"audit:exception:remove\",\"audit:exception:export\",\"monitor:online:list\",\"monitor:job:list\",\"monitor:data:list\",\"monitor:server:list\",\"monitor:cache:list\",\"monitor:online:query\",\"monitor:online:forceLogout\",\"monitor:job:query\",\"monitor:job:add\",\"monitor:job:edit\",\"monitor:job:remove\",\"monitor:job:execute\"],\"menus\":[{\"id\":1,\"name\":\"系统管理\",\"path\":\"\",\"icon\":\"Setting\",\"sort\":1,\"children\":[{\"id\":11,\"name\":\"用户管理\",\"path\":\"/users\",\"icon\":\"User\",\"parentId\":1,\"sort\":1},{\"id\":12,\"name\":\"角色管理\",\"path\":\"/roles\",\"icon\":\"UserFilled\",\"parentId\":1,\"sort\":2},{\"id\":13,\"name\":\"菜单管理\",\"path\":\"/menus\",\"icon\":\"Menu\",\"parentId\":1,\"sort\":3},{\"id\":14,\"name\":\"部门管理\",\"path\":\"/dept\",\"icon\":\"Document\",\"parentId\":1,\"sort\":4},{\"id\":15,\"name\":\"字典管理\",\"path\":\"/dict\",\"icon\":\"Collection\",\"parentId\":1,\"sort\":5},{\"id\":16,\"name\":\"参数管理\",\"path\":\"/sys/config\",\"icon\":\"Document\",\"parentId\":1,\"sort\":6},{\"id\":17,\"name\":\"通知公告\",\"path\":\"/notice\",\"icon\":\"Bell\",\"parentId\":1,\"sort\":7},{\"id\":18,\"name\":\"文件管理\",\"path\":\"/files\",\"icon\":\"Folder\",\"parentId\":1,\"sort\":8}]},{\"id\":2,\"name\":\"审计日志\",\"path\":\"\",\"icon\":\"Document\",\"sort\":2,\"children\":[{\"id\":21,\"name\":\"操作日志\",\"path\":\"/oplog\",\"icon\":\"Document\",\"parentId\":2,\"sort\":1},{\"id\":22,\"name\":\"登录日志\",\"path\":\"/loginlog\",\"icon\":\"Document\",\"parentId\":2,\"sort\":2},{\"id\":23,\"name\":\"异常日志\",\"path\":\"/exceptionlog\",\"icon\":\"Warning\",\"parentId\":2,\"sort\":3}]},{\"id\":3,\"name\":\"系统监控\",\"path\":\"\",\"icon\":\"Monitor\",\"sort\":3,\"children\":[{\"id\":31,\"name\":\"在线用户\",\"path\":\"/monitor/online\",\"icon\":\"Document\",\"parentId\":3,\"sort\":1},{\"id\":32,\"name\":\"定时任务\",\"path\":\"/monitor/job\",\"icon\":\"Document\",\"parentId\":3,\"sort\":2},{\"id\":33,\"name\":\"数据监控\",\"path\":\"/monitor/data\",\"icon\":\"Document\",\"parentId\":3,\"sort\":3},{\"id\":34,\"name\":\"服务监控\",\"path\":\"/monitor/server\",\"icon\":\"Document\",\"parentId\":3,\"sort\":4},{\"id\":35,\"name\":\"缓存监控\",\"path\":\"/monitor/cache\",\"icon\":\"Document\",\"parentId\":3,\"sort\":5}]}]}" + "value": "{\"roles\":[\"admin\"],\"permissions\":[\"system:user:list\",\"system:role:list\",\"system:menu:list\",\"system:dept:list\",\"system:dict:list\",\"system:config:list\",\"system:notice:list\",\"system:file:list\",\"system:user:query\",\"system:user:add\",\"system:user:edit\",\"system:user:remove\",\"system:user:export\",\"system:user:import\",\"system:user:resetPwd\",\"system:role:query\",\"system:role:add\",\"system:role:edit\",\"system:role:remove\",\"system:role:export\",\"system:menu:query\",\"system:menu:add\",\"system:menu:edit\",\"system:menu:remove\",\"audit:operation:list\",\"audit:login:list\",\"audit:exception:list\",\"audit:operation:query\",\"audit:operation:remove\",\"audit:operation:export\",\"audit:login:query\",\"audit:login:remove\",\"audit:login:export\",\"audit:exception:query\",\"audit:exception:remove\",\"audit:exception:export\",\"monitor:online:list\",\"monitor:job:list\",\"monitor:data:list\",\"monitor:server:list\",\"monitor:cache:list\",\"monitor:online:query\",\"monitor:online:forceLogout\",\"monitor:job:query\",\"monitor:job:add\",\"monitor:job:edit\",\"monitor:job:remove\",\"monitor:job:execute\"],\"menus\":[{\"id\":\"1\",\"name\":\"系统管理\",\"path\":\"\",\"icon\":\"Setting\",\"sort\":1,\"children\":[{\"id\":\"11\",\"name\":\"用户管理\",\"path\":\"/users\",\"icon\":\"User\",\"parentId\":\"1\",\"sort\":1},{\"id\":\"12\",\"name\":\"角色管理\",\"path\":\"/roles\",\"icon\":\"UserFilled\",\"parentId\":\"1\",\"sort\":2},{\"id\":\"13\",\"name\":\"菜单管理\",\"path\":\"/menus\",\"icon\":\"Menu\",\"parentId\":\"1\",\"sort\":3},{\"id\":\"14\",\"name\":\"部门管理\",\"path\":\"/dept\",\"icon\":\"Document\",\"parentId\":\"1\",\"sort\":4},{\"id\":\"15\",\"name\":\"字典管理\",\"path\":\"/dict\",\"icon\":\"Collection\",\"parentId\":\"1\",\"sort\":5},{\"id\":\"16\",\"name\":\"参数管理\",\"path\":\"/sys/config\",\"icon\":\"Document\",\"parentId\":\"1\",\"sort\":6},{\"id\":\"17\",\"name\":\"通知公告\",\"path\":\"/notice\",\"icon\":\"Bell\",\"parentId\":\"1\",\"sort\":7},{\"id\":\"18\",\"name\":\"文件管理\",\"path\":\"/files\",\"icon\":\"Folder\",\"parentId\":\"1\",\"sort\":8}]},{\"id\":\"2\",\"name\":\"审计日志\",\"path\":\"\",\"icon\":\"Document\",\"sort\":2,\"children\":[{\"id\":\"21\",\"name\":\"操作日志\",\"path\":\"/oplog\",\"icon\":\"Document\",\"parentId\":\"2\",\"sort\":1},{\"id\":\"22\",\"name\":\"登录日志\",\"path\":\"/loginlog\",\"icon\":\"Document\",\"parentId\":\"2\",\"sort\":2},{\"id\":\"23\",\"name\":\"异常日志\",\"path\":\"/exceptionlog\",\"icon\":\"Warning\",\"parentId\":\"2\",\"sort\":3}]},{\"id\":\"3\",\"name\":\"系统监控\",\"path\":\"\",\"icon\":\"Monitor\",\"sort\":3,\"children\":[{\"id\":\"31\",\"name\":\"在线用户\",\"path\":\"/monitor/online\",\"icon\":\"Document\",\"parentId\":\"3\",\"sort\":1},{\"id\":\"32\",\"name\":\"定时任务\",\"path\":\"/monitor/job\",\"icon\":\"Document\",\"parentId\":\"3\",\"sort\":2},{\"id\":\"33\",\"name\":\"数据监控\",\"path\":\"/monitor/data\",\"icon\":\"Document\",\"parentId\":\"3\",\"sort\":3},{\"id\":\"34\",\"name\":\"服务监控\",\"path\":\"/monitor/server\",\"icon\":\"Document\",\"parentId\":\"3\",\"sort\":4},{\"id\":\"35\",\"name\":\"缓存监控\",\"path\":\"/monitor/cache\",\"icon\":\"Document\",\"parentId\":\"3\",\"sort\":5}]}]}" }, { "name": "userId", diff --git a/playwright/.auth/user.json b/playwright/.auth/user.json index 2f29366..3e05e59 100644 --- a/playwright/.auth/user.json +++ b/playwright/.auth/user.json @@ -6,7 +6,7 @@ "localStorage": [ { "name": "token", - "value": "eyJhbGciOiJIUzM4NCJ9.eyJyb2xlcyI6WyJhZG1pbiJdLCJ1c2VySWQiOjEsInVzZXJuYW1lIjoiYWRtaW4iLCJzdWIiOiJhZG1pbiIsImlhdCI6MTc3NjQ4NzA2OSwiZXhwIjoxNzc2NTczNDY5fQ.ZOxLUv_Iu1LUiHYEAPkeZsGpzVw813_kIdz1oQHCxLt_Yi-o7lx90sPU55XmFqPp" + "value": "eyJhbGciOiJIUzM4NCJ9.eyJyb2xlcyI6WyJhZG1pbiJdLCJ1c2VySWQiOjEsInVzZXJuYW1lIjoiYWRtaW4iLCJzdWIiOiJhZG1pbiIsImlhdCI6MTc3NjkzMTI3MywiZXhwIjoxNzc3MDE3NjczfQ.eCEHzq6AHcxhkmhxSSbmM-F5RShM9_GEqQ3McmA8Pyg3CNQ4TXf6HLEDtzdUNY0q" }, { "name": "permission", diff --git a/test-suite/pytest.ini b/test-suite/pytest.ini index 7e7cea7..324aa35 100644 --- a/test-suite/pytest.ini +++ b/test-suite/pytest.ini @@ -8,10 +8,7 @@ addopts = -v --strict-markers --tb=short - --cov=. - --cov-report=html - --cov-report=term-missing - --alluredir=allure-results + -p no:allure markers = unit: 单元测试 auth: 认证相关测试 diff --git a/test-suite/reports/test-report.html b/test-suite/reports/test-report.html new file mode 100644 index 0000000..a707352 --- /dev/null +++ b/test-suite/reports/test-report.html @@ -0,0 +1,1091 @@ + + + + + test-report.html + + + + +

test-report.html

+

Report generated on 23-Apr-2026 at 07:04:16 by pytest-html + v4.1.1

+
+

Environment

+
+
+ + + + + +
+
+

Summary

+
+
+

0 test took 0 ms.

+

(Un)check the boxes to filter the results.

+
+ +
+
+
+
+ + 0 Failed, + + 0 Passed, + + 0 Skipped, + + 0 Expected failures, + + 0 Unexpected passes, + + 1 Errors, + + 0 Reruns +
+
+  /  +
+
+
+
+
+
+
+
+ + + + + + + + + +
ResultTestDurationLinks
+ + + \ No newline at end of file diff --git a/test-suite/tests/e2e/test_gateway_directly.py b/test-suite/tests/e2e/test_gateway_directly.py index e479470..5176f01 100644 --- a/test-suite/tests/e2e/test_gateway_directly.py +++ b/test-suite/tests/e2e/test_gateway_directly.py @@ -5,15 +5,16 @@ import requests import time +from config.settings import settings # 先登录获取Token login_data = { - "username": "admin", - "password": "admin123" + "username": settings.TEST_USERNAME, + "password": settings.TEST_PASSWORD } print("1. 登录...") -response = requests.post("http://localhost:8080/api/auth/login", json=login_data) +response = requests.post(f"{settings.API_BASE_URL}/api/auth/login", json=login_data) print(f"状态码: {response.status_code}") print(f"响应: {response.text[:200]}...") @@ -27,12 +28,12 @@ if response.status_code == 200: "Authorization": f"Bearer {token}" } - response2 = requests.get("http://localhost:8080/api/users/page?page=0&size=10", headers=headers) + response2 = requests.get(f"{settings.API_BASE_URL}/api/users/page?page=0&size=10", headers=headers) print(f"状态码: {response2.status_code}") print(f"响应: {response2.text[:200]}...") # 测试用户统计API print("\n3. 测试用户统计API...") - response3 = requests.get("http://localhost:8080/api/users/count", headers=headers) + response3 = requests.get(f"{settings.API_BASE_URL}/api/users/count", headers=headers) print(f"状态码: {response3.status_code}") print(f"响应: {response3.text[:200]}...") diff --git a/test-suite/user_journey_test.py b/test-suite/user_journey_test.py new file mode 100644 index 0000000..a2dc548 --- /dev/null +++ b/test-suite/user_journey_test.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python3 +""" +User Journey 测试脚本 +测试完整的用户流程 +""" + +import requests +import json +import time + +API_BASE_URL = "http://localhost:8084" + +def print_step(step_num, description): + print(f"\n{'='*60}") + print(f"步骤 {step_num}: {description}") + print('='*60) + +def test_user_journey(): + """测试完整的用户旅程""" + + # 步骤 1: 登录 + print_step(1, "用户登录") + login_data = { + "username": "admin", + "password": "admin123" + } + response = requests.post(f"{API_BASE_URL}/api/auth/login", json=login_data) + print(f"状态码: {response.status_code}") + + if response.status_code != 200: + print(f"❌ 登录失败: {response.text}") + return False + + token_data = response.json() + token = token_data.get("token") + print(f"✅ 登录成功") + print(f"用户: {token_data.get('username')}") + print(f"Token: {token[:50]}...") + + headers = {"Authorization": f"Bearer {token}"} + + # 步骤 2: 获取用户列表 + print_step(2, "获取用户列表") + response = requests.get(f"{API_BASE_URL}/api/users", headers=headers) + print(f"状态码: {response.status_code}") + + if response.status_code == 200: + users = response.json() + print(f"✅ 获取用户列表成功") + print(f"用户数量: {len(users) if isinstance(users, list) else 'N/A'}") + else: + print(f"⚠️ 获取用户列表失败: {response.text[:200]}") + + # 步骤 3: 创建新用户 + print_step(3, "创建新用户") + timestamp = int(time.time() * 1000) + new_user = { + "username": f"testuser_{timestamp}", + "password": "Test@123", + "email": f"test_{timestamp}@example.com", + "phone": "13800138000", + "nickname": f"测试用户_{timestamp}", + "status": 1, + "roleId": 2 + } + response = requests.post(f"{API_BASE_URL}/api/users", json=new_user, headers=headers) + print(f"状态码: {response.status_code}") + + if response.status_code in [200, 201]: + created_user = response.json() + user_id = created_user.get("id") or created_user.get("data", {}).get("id") + print(f"✅ 创建用户成功") + print(f"用户ID: {user_id}") + print(f"用户名: {new_user['username']}") + else: + print(f"⚠️ 创建用户失败: {response.text[:200]}") + user_id = None + + # 步骤 4: 更新用户信息 + if user_id: + print_step(4, "更新用户信息") + update_data = { + "nickname": f"更新后的用户_{timestamp}", + "email": f"updated_{timestamp}@example.com" + } + response = requests.put(f"{API_BASE_URL}/api/users/{user_id}", json=update_data, headers=headers) + print(f"状态码: {response.status_code}") + + if response.status_code == 200: + print(f"✅ 更新用户成功") + else: + print(f"⚠️ 更新用户失败: {response.text[:200]}") + + # 步骤 5: 获取角色列表 + print_step(5, "获取角色列表") + response = requests.get(f"{API_BASE_URL}/api/roles", headers=headers) + print(f"状态码: {response.status_code}") + + if response.status_code == 200: + roles = response.json() + print(f"✅ 获取角色列表成功") + print(f"角色数量: {len(roles) if isinstance(roles, list) else 'N/A'}") + else: + print(f"⚠️ 获取角色列表失败: {response.text[:200]}") + + # 步骤 6: 获取菜单列表 + print_step(6, "获取菜单列表") + response = requests.get(f"{API_BASE_URL}/api/menus", headers=headers) + print(f"状态码: {response.status_code}") + + if response.status_code == 200: + menus = response.json() + print(f"✅ 获取菜单列表成功") + print(f"菜单数量: {len(menus) if isinstance(menus, list) else 'N/A'}") + else: + print(f"⚠️ 获取菜单列表失败: {response.text[:200]}") + + # 步骤 7: 删除测试用户 + if user_id: + print_step(7, "删除测试用户") + response = requests.delete(f"{API_BASE_URL}/api/users/{user_id}", headers=headers) + print(f"状态码: {response.status_code}") + + if response.status_code in [200, 204]: + print(f"✅ 删除用户成功") + else: + print(f"⚠️ 删除用户失败: {response.text[:200]}") + + # 步骤 8: 登出 + print_step(8, "用户登出") + response = requests.post(f"{API_BASE_URL}/api/auth/logout", headers=headers) + print(f"状态码: {response.status_code}") + + if response.status_code == 200: + print(f"✅ 登出成功") + else: + print(f"⚠️ 登出失败: {response.text[:200]}") + + print(f"\n{'='*60}") + print("User Journey 测试完成") + print('='*60) + + return True + +if __name__ == "__main__": + test_user_journey()