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
This commit is contained in:
张翔
2026-04-23 16:35:57 +08:00
parent f590c40c21
commit 0d0b4decc3
14 changed files with 1327 additions and 151 deletions
-5
View File
@@ -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 }) => {
+37 -84
View File
@@ -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('受保护页面访问验证通过');
});
});
});
+9 -7
View File
@@ -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: 页面导航
+3 -12
View File
@@ -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();
@@ -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' });
});
+3 -12
View File
@@ -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();
@@ -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}`);
}
});
});
+3 -12
View File
@@ -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();
+2 -2
View File
@@ -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",
+1 -1
View File
@@ -6,7 +6,7 @@
"localStorage": [
{
"name": "token",
"value": "eyJhbGciOiJIUzM4NCJ9.eyJyb2xlcyI6WyJhZG1pbiJdLCJ1c2VySWQiOjEsInVzZXJuYW1lIjoiYWRtaW4iLCJzdWIiOiJhZG1pbiIsImlhdCI6MTc3NjQ4NzA2OSwiZXhwIjoxNzc2NTczNDY5fQ.ZOxLUv_Iu1LUiHYEAPkeZsGpzVw813_kIdz1oQHCxLt_Yi-o7lx90sPU55XmFqPp"
"value": "eyJhbGciOiJIUzM4NCJ9.eyJyb2xlcyI6WyJhZG1pbiJdLCJ1c2VySWQiOjEsInVzZXJuYW1lIjoiYWRtaW4iLCJzdWIiOiJhZG1pbiIsImlhdCI6MTc3NjkzMTI3MywiZXhwIjoxNzc3MDE3NjczfQ.eCEHzq6AHcxhkmhxSSbmM-F5RShM9_GEqQ3McmA8Pyg3CNQ4TXf6HLEDtzdUNY0q"
},
{
"name": "permission",
+1 -4
View File
@@ -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: 认证相关测试
File diff suppressed because one or more lines are too long
@@ -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]}...")
+146
View File
@@ -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()