Files
everything-is-suitable/everything-is-suitable-test/test-tools/test_cases/api_tests_enhanced.py
T
张翔 08ea5fbe98 feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
2026-03-28 14:37:29 +08:00

711 lines
20 KiB
Python

"""
API测试用例模块(增强版)
支持参数化测试、边界条件测试和异常场景测试
"""
from typing import List, Dict, Any, Callable
from functools import wraps
import pytest
from core.api_tester import APITester
from core.validation import ValidationRule
from data.test_data import TestDataGenerator
def ensure_auth(test_func: Callable) -> Callable:
"""
装饰器:确保测试前已认证
Args:
test_func: 测试函数
Returns:
包装后的测试函数
"""
@wraps(test_func)
def wrapper(self, *args, **kwargs):
# 确保已认证
if not self.tester._ensure_authenticated():
return False
return test_func(self, *args, **kwargs)
return wrapper
class APITestCases:
"""API测试用例集合(增强版)"""
def __init__(self, tester: APITester):
"""
初始化测试用例
Args:
tester: API测试器实例
"""
self.tester = tester
self.test_data_generator = TestDataGenerator()
self.created_user_id = None
self.created_role_id = None
@ensure_auth
def test_health_check(self) -> bool:
"""
测试健康检查接口
Returns:
是否通过
"""
result = self.tester.request(
"GET",
"/actuator/health",
test_name="健康检查",
expected_status=200,
require_auth=False
)
validation_rules = [
ValidationRule("status_code", 200),
ValidationRule("json_path", "UP", path="status")
]
result = self.tester.validate(result, validation_rules)
return result.passed
def test_login(self, username: str = None, password: str = None) -> bool:
"""
测试用户登录
Args:
username: 用户名
password: 密码
Returns:
是否通过
"""
username = username or "admin"
password = password or "admin123"
result = self.tester.request(
"POST",
"/auth/login",
data={"username": username, "password": password},
test_name="用户登录",
expected_status=200,
require_auth=False
)
validation_rules = [
ValidationRule("status_code", 200),
ValidationRule("json_path", 200, path="code"),
ValidationRule("json_path", "token", path="data.token")
]
result = self.tester.validate(result, validation_rules)
return result.passed
@ensure_auth
def test_get_user_list(self) -> bool:
"""
测试获取用户列表
Returns:
是否通过
"""
result = self.tester.request(
"GET",
"/user/list",
params={"page": 1, "pageSize": 10},
test_name="获取用户列表",
expected_status=200
)
validation_rules = [
ValidationRule("status_code", 200),
ValidationRule("json_path", 200, path="code"),
ValidationRule("json_path", "records", path="data")
]
result = self.tester.validate(result, validation_rules)
return result.passed
@ensure_auth
def test_get_role_list(self) -> bool:
"""
测试获取角色列表
Returns:
是否通过
"""
result = self.tester.request(
"GET",
"/role/list",
params={"page": 1, "pageSize": 10},
test_name="获取角色列表",
expected_status=200
)
validation_rules = [
ValidationRule("status_code", 200),
ValidationRule("json_path", 200, path="code"),
ValidationRule("json_path", "records", path="data")
]
result = self.tester.validate(result, validation_rules)
return result.passed
@ensure_auth
def test_get_menu_list(self) -> bool:
"""
测试获取菜单列表
Returns:
是否通过
"""
result = self.tester.request(
"GET",
"/menu/list",
test_name="获取菜单列表",
expected_status=200
)
validation_rules = [
ValidationRule("status_code", 200),
ValidationRule("json_path", 200, path="code"),
ValidationRule("json_path", "list", path="data")
]
result = self.tester.validate(result, validation_rules)
return result.passed
@ensure_auth
def test_create_user(self) -> bool:
"""
测试创建用户
Returns:
是否通过
"""
user_data = self.test_data_generator.generate_user_data()
result = self.tester.request(
"POST",
"/user/create",
data=user_data,
test_name="创建用户",
expected_status=200
)
validation_rules = [
ValidationRule("status_code", 200),
ValidationRule("json_path", 200, path="code"),
ValidationRule("json_path", user_data["username"], path="data.username")
]
result = self.tester.validate(result, validation_rules)
# 保存创建的用户ID
if result.passed and result.response_data.get("data"):
self.created_user_id = result.response_data["data"].get("id")
return result.passed
@ensure_auth
def test_create_role(self) -> bool:
"""
测试创建角色
Returns:
是否通过
"""
role_data = self.test_data_generator.generate_role_data()
result = self.tester.request(
"POST",
"/role/create",
data=role_data,
test_name="创建角色",
expected_status=200
)
validation_rules = [
ValidationRule("status_code", 200),
ValidationRule("json_path", 200, path="code"),
ValidationRule("json_path", role_data["roleName"], path="data.roleName")
]
result = self.tester.validate(result, validation_rules)
# 保存创建的角色ID
if result.passed and result.response_data.get("data"):
self.created_role_id = result.response_data["data"].get("id")
return result.passed
@ensure_auth
def test_update_user(self, user_id: int = None) -> bool:
"""
测试更新用户
Args:
user_id: 用户ID
Returns:
是否通过
"""
user_data = self.test_data_generator.generate_user_data()
if user_id:
user_data["id"] = user_id
elif self.created_user_id:
user_data["id"] = self.created_user_id
result = self.tester.request(
"PUT",
"/user/update",
data=user_data,
test_name="更新用户",
expected_status=200
)
validation_rules = [
ValidationRule("status_code", 200),
ValidationRule("json_path", 200, path="code")
]
result = self.tester.validate(result, validation_rules)
return result.passed
@ensure_auth
def test_delete_user(self, user_id: int = None) -> bool:
"""
测试删除用户
Args:
user_id: 用户ID
Returns:
是否通过
"""
if user_id is None:
user_id = self.created_user_id
if user_id is None:
return False
result = self.tester.request(
"DELETE",
f"/user/delete/{user_id}",
test_name="删除用户",
expected_status=200
)
validation_rules = [
ValidationRule("status_code", 200),
ValidationRule("json_path", 200, path="code")
]
result = self.tester.validate(result, validation_rules)
return result.passed
@ensure_auth
def test_get_user_info(self, user_id: int = None) -> bool:
"""
测试获取用户信息
Args:
user_id: 用户ID
Returns:
是否通过
"""
if user_id is None:
user_id = self.created_user_id
if user_id is None:
return False
result = self.tester.request(
"GET",
f"/user/info/{user_id}",
test_name="获取用户信息",
expected_status=200
)
validation_rules = [
ValidationRule("status_code", 200),
ValidationRule("json_path", 200, path="code"),
ValidationRule("json_path", user_id, path="data.id")
]
result = self.tester.validate(result, validation_rules)
return result.passed
@ensure_auth
def test_search_users(self, keyword: str = None) -> bool:
"""
测试搜索用户
Args:
keyword: 搜索关键词
Returns:
是否通过
"""
keyword = keyword or "admin"
result = self.tester.request(
"GET",
"/user/search",
params={"keyword": keyword, "page": 1, "pageSize": 10},
test_name="搜索用户",
expected_status=200
)
validation_rules = [
ValidationRule("status_code", 200),
ValidationRule("json_path", 200, path="code"),
ValidationRule("json_path", "records", path="data")
]
result = self.tester.validate(result, validation_rules)
return result.passed
def run_all_tests(self) -> Dict[str, bool]:
"""
运行所有基础测试用例
Returns:
测试结果字典
"""
results = {}
# 健康检查
results["health_check"] = self.test_health_check()
# 登录
results["login"] = self.test_login()
# 获取列表
results["get_user_list"] = self.test_get_user_list()
results["get_role_list"] = self.test_get_role_list()
results["get_menu_list"] = self.test_get_menu_list()
# 创建
results["create_user"] = self.test_create_user()
results["create_role"] = self.test_create_role()
# 搜索
results["search_users"] = self.test_search_users()
return results
class ParameterizedTestCases:
"""参数化测试用例"""
def __init__(self, tester: APITester):
"""
初始化参数化测试用例
Args:
tester: API测试器实例
"""
self.tester = tester
self.test_data_generator = TestDataGenerator()
@ensure_auth
def test_login_with_different_credentials(self, credentials: List[Dict[str, str]]) -> Dict[str, bool]:
"""
使用不同凭据测试登录
Args:
credentials: 凭据列表,每个元素包含username和password
Returns:
测试结果字典
"""
results = {}
for cred in credentials:
username = cred.get("username")
password = cred.get("password")
test_name = f"登录测试 - {username}"
result = self.tester.request(
"POST",
"/auth/login",
data={"username": username, "password": password},
test_name=test_name,
expected_status=200,
require_auth=False
)
validation_rules = [
ValidationRule("status_code", 200),
ValidationRule("json_path", 200, path="code")
]
result = self.tester.validate(result, validation_rules)
results[test_name] = result.passed
return results
@ensure_auth
def test_pagination(self, page_sizes: List[int]) -> Dict[str, bool]:
"""
测试分页功能
Args:
page_sizes: 页面大小列表
Returns:
测试结果字典
"""
results = {}
for page_size in page_sizes:
test_name = f"分页测试 - 页面大小: {page_size}"
result = self.tester.request(
"GET",
"/user/list",
params={"page": 1, "pageSize": page_size},
test_name=test_name,
expected_status=200
)
validation_rules = [
ValidationRule("status_code", 200),
ValidationRule("json_path", 200, path="code"),
ValidationRule("json_path", "records", path="data")
]
result = self.tester.validate(result, validation_rules)
results[test_name] = result.passed
return results
class BoundaryTestCases:
"""边界条件测试用例"""
def __init__(self, tester: APITester):
"""
初始化边界条件测试用例
Args:
tester: API测试器实例
"""
self.tester = tester
self.test_data_generator = TestDataGenerator()
@ensure_auth
def test_user_name_length(self) -> Dict[str, bool]:
"""
测试用户名长度边界
Returns:
测试结果字典
"""
results = {}
# 测试空用户名
result = self.tester.request(
"POST",
"/auth/login",
data={"username": "", "password": "admin123"},
test_name="登录测试 - 空用户名",
expected_status=400,
require_auth=False
)
results["空用户名"] = result.status_code == 400
# 测试超长用户名
long_username = "a" * 100
result = self.tester.request(
"POST",
"/auth/login",
data={"username": long_username, "password": "admin123"},
test_name="登录测试 - 超长用户名",
expected_status=400,
require_auth=False
)
results["超长用户名"] = result.status_code == 400
return results
@ensure_auth
def test_page_size_boundaries(self) -> Dict[str, bool]:
"""
测试页面大小边界
Returns:
测试结果字典
"""
results = {}
# 测试页面大小为0
result = self.tester.request(
"GET",
"/user/list",
params={"page": 1, "pageSize": 0},
test_name="分页测试 - 页面大小为0",
expected_status=400
)
results["页面大小为0"] = result.status_code == 400
# 测试页面大小为负数
result = self.tester.request(
"GET",
"/user/list",
params={"page": 1, "pageSize": -1},
test_name="分页测试 - 页面大小为负数",
expected_status=400
)
results["页面大小为负数"] = result.status_code == 400
# 测试超大页面大小
result = self.tester.request(
"GET",
"/user/list",
params={"page": 1, "pageSize": 10000},
test_name="分页测试 - 超大页面大小",
expected_status=200
)
results["超大页面大小"] = result.status_code == 200
return results
class ExceptionTestCases:
"""异常场景测试用例"""
def __init__(self, tester: APITester):
"""
初始化异常场景测试用例
Args:
tester: API测试器实例
"""
self.tester = tester
self.test_data_generator = TestDataGenerator()
@ensure_auth
def test_invalid_credentials(self) -> Dict[str, bool]:
"""
测试无效凭据
Returns:
测试结果字典
"""
results = {}
# 测试错误密码
result = self.tester.request(
"POST",
"/auth/login",
data={"username": "admin", "password": "wrongpassword"},
test_name="登录测试 - 错误密码",
expected_status=401,
require_auth=False
)
results["错误密码"] = result.status_code == 401
# 测试不存在的用户
result = self.tester.request(
"POST",
"/auth/login",
data={"username": "nonexistent", "password": "admin123"},
test_name="登录测试 - 不存在的用户",
expected_status=401,
require_auth=False
)
results["不存在的用户"] = result.status_code == 401
return results
@ensure_auth
def test_missing_required_fields(self) -> Dict[str, bool]:
"""
测试缺少必填字段
Returns:
测试结果字典
"""
results = {}
# 测试缺少用户名
result = self.tester.request(
"POST",
"/auth/login",
data={"password": "admin123"},
test_name="登录测试 - 缺少用户名",
expected_status=400,
require_auth=False
)
results["缺少用户名"] = result.status_code == 400
# 测试缺少密码
result = self.tester.request(
"POST",
"/auth/login",
data={"username": "admin"},
test_name="登录测试 - 缺少密码",
expected_status=400,
require_auth=False
)
results["缺少密码"] = result.status_code == 400
return results
@ensure_auth
def test_unauthorized_access(self) -> Dict[str, bool]:
"""
测试未授权访问
Returns:
测试结果字典
"""
results = {}
# 临时清除认证
self.tester.auth_manager.logout()
# 测试未授权访问用户列表
result = self.tester.request(
"GET",
"/user/list",
test_name="未授权访问 - 用户列表",
expected_status=401,
require_auth=False
)
results["未授权访问用户列表"] = result.status_code == 401
# 重新认证
self.tester._ensure_authenticated()
return results
@ensure_auth
def test_invalid_http_methods(self) -> Dict[str, bool]:
"""
测试无效的HTTP方法
Returns:
测试结果字典
"""
results = {}
# 测试不支持的HTTP方法
try:
result = self.tester.request(
"PATCH",
"/user/list",
test_name="无效HTTP方法 - PATCH",
expected_status=405
)
results["PATCH方法"] = result.status_code == 405
except:
results["PATCH方法"] = False
return results