1e3dc11d59
feat(test-suite): 新增测试套件模块,包含API测试客户端和测试配置 fix(api): 修复数据库实体和仓库的删除操作返回值 style(api): 统一数据库表名和字段命名 perf(api): 添加缓存注解提升配置查询性能 test(api): 添加H2测试数据库配置支持 chore: 清理旧的测试文件和脚本
537 lines
19 KiB
Python
537 lines
19 KiB
Python
"""
|
|
UAT业务场景验收测试
|
|
|
|
测试范围:
|
|
1. 新员工入职流程
|
|
2. 员工离职流程
|
|
3. 权限变更流程
|
|
4. 组织架构调整流程
|
|
5. 系统配置变更流程
|
|
"""
|
|
|
|
import pytest
|
|
import time
|
|
import uuid
|
|
import asyncio
|
|
from typing import Dict, Any
|
|
from api.auth_api import AuthAPI
|
|
from api.user_api import UserAPI
|
|
from api.role_api import RoleAPI
|
|
from api.menu_api import MenuAPI
|
|
from api.config_api import ConfigAPI
|
|
from api.audit_api import AuditAPI
|
|
from config.settings import settings
|
|
|
|
|
|
@pytest.mark.uat
|
|
@pytest.mark.business_scenario
|
|
@pytest.mark.asyncio
|
|
class TestBusinessScenarioUAT:
|
|
"""业务场景验收测试类"""
|
|
|
|
@pytest.fixture
|
|
async def authenticated_client(self):
|
|
"""已认证的HTTP客户端"""
|
|
async with AuthAPI.create_client() as client:
|
|
auth_api = AuthAPI(client)
|
|
await auth_api.login(settings.TEST_USERNAME, settings.TEST_PASSWORD)
|
|
yield client
|
|
|
|
@pytest.fixture
|
|
async def test_data_manager(self):
|
|
"""测试数据管理器"""
|
|
from utils.test_data_manager import TestDataManager
|
|
manager = TestDataManager()
|
|
yield manager
|
|
await manager.cleanup_all()
|
|
|
|
async def test_bs_new_employee_onboarding(
|
|
self, authenticated_client, test_data_manager
|
|
):
|
|
"""
|
|
BS-01: 新员工入职流程
|
|
|
|
业务场景:
|
|
1. HR创建新员工账户
|
|
2. 分配基础角色(普通员工)
|
|
3. 员工首次登录并修改密码
|
|
4. 员工完善个人信息
|
|
5. 验证权限范围
|
|
|
|
验收标准:
|
|
- 账户创建成功
|
|
- 角色分配正确
|
|
- 首次登录强制修改密码
|
|
- 个人信息可更新
|
|
- 权限范围符合预期
|
|
"""
|
|
user_api = UserAPI(authenticated_client)
|
|
role_api = RoleAPI(authenticated_client)
|
|
auth_api = AuthAPI(authenticated_client)
|
|
|
|
unique_id = f"onboard_{int(time.time() * 1000)}_{uuid.uuid4().hex[:8]}"
|
|
|
|
employee_role_data = {
|
|
"roleName": f"新员工角色_{unique_id}",
|
|
"roleKey": f"employee_role_{unique_id}",
|
|
"roleSort": 10,
|
|
"status": 1,
|
|
"remark": "业务场景测试-新员工角色"
|
|
}
|
|
role_response = await role_api.create_role(employee_role_data)
|
|
assert role_response.status_code == 201, "创建员工角色失败"
|
|
role_id = role_response.json()["id"]
|
|
test_data_manager.add_role(role_id)
|
|
|
|
employee_data = {
|
|
"username": f"new_employee_{unique_id}",
|
|
"password": "Welcome123!@#",
|
|
"email": f"new_employee_{unique_id}@company.com",
|
|
"phone": f"138001380{unique_id[-4:]}",
|
|
"roleId": role_id,
|
|
"status": 1,
|
|
"remark": "业务场景测试-新入职员工"
|
|
}
|
|
user_response = await user_api.create_user(employee_data)
|
|
assert user_response.status_code == 201, "创建员工账户失败"
|
|
user_id = user_response.json()["id"]
|
|
test_data_manager.add_user(user_id)
|
|
|
|
login_response = await auth_api.login(
|
|
f"new_employee_{unique_id}",
|
|
"Welcome123!@#"
|
|
)
|
|
assert login_response.status_code == 200, "员工登录失败"
|
|
login_data = login_response.json()
|
|
assert "token" in login_data, "登录应返回token"
|
|
|
|
profile_data = {
|
|
"nickName": f"张三_{unique_id}",
|
|
"phone": f"139001390{unique_id[-4:]}",
|
|
"remark": "业务场景测试-完善个人信息"
|
|
}
|
|
profile_response = await user_api.update_user_profile(profile_data)
|
|
assert profile_response.status_code == 200, "更新个人信息失败"
|
|
|
|
permissions_response = await role_api.get_role_permissions(role_id)
|
|
assert permissions_response.status_code == 200, "获取权限失败"
|
|
|
|
await user_api.delete_user(user_id)
|
|
test_data_manager._users.remove(user_id)
|
|
await role_api.delete_role(role_id)
|
|
test_data_manager._roles.remove(role_id)
|
|
|
|
async def test_bs_employee_resignation(
|
|
self, authenticated_client, test_data_manager
|
|
):
|
|
"""
|
|
BS-02: 员工离职流程
|
|
|
|
业务场景:
|
|
1. 员工提交离职申请
|
|
2. 管理员禁用员工账户
|
|
3. 回收员工权限
|
|
4. 归档员工数据
|
|
5. 验证账户无法登录
|
|
|
|
验收标准:
|
|
- 账户状态变更为禁用
|
|
- 权限已回收
|
|
- 数据已归档
|
|
- 无法登录系统
|
|
"""
|
|
user_api = UserAPI(authenticated_client)
|
|
role_api = RoleAPI(authenticated_client)
|
|
auth_api = AuthAPI(authenticated_client)
|
|
|
|
unique_id = f"resign_{int(time.time() * 1000)}_{uuid.uuid4().hex[:8]}"
|
|
|
|
role_data = {
|
|
"roleName": f"离职测试角色_{unique_id}",
|
|
"roleKey": f"resign_role_{unique_id}",
|
|
"roleSort": 10,
|
|
"status": 1
|
|
}
|
|
role_response = await role_api.create_role(role_data)
|
|
assert role_response.status_code == 201
|
|
role_id = role_response.json()["id"]
|
|
test_data_manager.add_role(role_id)
|
|
|
|
user_data = {
|
|
"username": f"resign_employee_{unique_id}",
|
|
"password": "Test123!@#",
|
|
"email": f"resign_{unique_id}@company.com",
|
|
"roleId": role_id,
|
|
"status": 1
|
|
}
|
|
user_response = await user_api.create_user(user_data)
|
|
assert user_response.status_code == 201
|
|
user_id = user_response.json()["id"]
|
|
test_data_manager.add_user(user_id)
|
|
|
|
disable_data = {"status": 0}
|
|
disable_response = await user_api.update_user(user_id, disable_data)
|
|
assert disable_response.status_code == 200, "禁用账户失败"
|
|
|
|
user_detail = await user_api.get_user_by_id(user_id)
|
|
assert user_detail.status_code == 200
|
|
user_info = user_detail.json()
|
|
assert user_info["status"] == 0, "账户状态应为禁用"
|
|
|
|
login_response = await auth_api.login(
|
|
f"resign_employee_{unique_id}",
|
|
"Test123!@#"
|
|
)
|
|
assert login_response.status_code != 200, "已禁用账户不应能登录"
|
|
|
|
await user_api.delete_user(user_id)
|
|
test_data_manager._users.remove(user_id)
|
|
await role_api.delete_role(role_id)
|
|
test_data_manager._roles.remove(role_id)
|
|
|
|
async def test_bs_permission_change(
|
|
self, authenticated_client, test_data_manager
|
|
):
|
|
"""
|
|
BS-03: 权限变更流程
|
|
|
|
业务场景:
|
|
1. 员工晋升为经理
|
|
2. 更新角色权限
|
|
3. 验证新权限即时生效
|
|
4. 验证旧权限已撤销
|
|
|
|
验收标准:
|
|
- 角色变更成功
|
|
- 新权限立即生效
|
|
- 旧权限已撤销
|
|
- 审计日志记录完整
|
|
"""
|
|
user_api = UserAPI(authenticated_client)
|
|
role_api = RoleAPI(authenticated_client)
|
|
menu_api = MenuAPI(authenticated_client)
|
|
|
|
unique_id = f"perm_{int(time.time() * 1000)}_{uuid.uuid4().hex[:8]}"
|
|
|
|
employee_role_data = {
|
|
"roleName": f"员工角色_{unique_id}",
|
|
"roleKey": f"emp_role_{unique_id}",
|
|
"roleSort": 10,
|
|
"status": 1
|
|
}
|
|
emp_role_response = await role_api.create_role(employee_role_data)
|
|
assert emp_role_response.status_code == 201
|
|
emp_role_id = emp_role_response.json()["id"]
|
|
test_data_manager.add_role(emp_role_id)
|
|
|
|
manager_role_data = {
|
|
"roleName": f"经理角色_{unique_id}",
|
|
"roleKey": f"mgr_role_{unique_id}",
|
|
"roleSort": 5,
|
|
"status": 1
|
|
}
|
|
mgr_role_response = await role_api.create_role(manager_role_data)
|
|
assert mgr_role_response.status_code == 201
|
|
mgr_role_id = mgr_role_response.json()["id"]
|
|
test_data_manager.add_role(mgr_role_id)
|
|
|
|
user_data = {
|
|
"username": f"perm_user_{unique_id}",
|
|
"password": "Test123!@#",
|
|
"email": f"perm_{unique_id}@company.com",
|
|
"roleId": emp_role_id,
|
|
"status": 1
|
|
}
|
|
user_response = await user_api.create_user(user_data)
|
|
assert user_response.status_code == 201
|
|
user_id = user_response.json()["id"]
|
|
test_data_manager.add_user(user_id)
|
|
|
|
user_before = await user_api.get_user_by_id(user_id)
|
|
assert user_before.json()["roleId"] == emp_role_id
|
|
|
|
update_data = {"roleId": mgr_role_id}
|
|
update_response = await user_api.update_user(user_id, update_data)
|
|
assert update_response.status_code == 200, "角色变更失败"
|
|
|
|
user_after = await user_api.get_user_by_id(user_id)
|
|
assert user_after.json()["roleId"] == mgr_role_id, "角色变更未生效"
|
|
|
|
await user_api.delete_user(user_id)
|
|
test_data_manager._users.remove(user_id)
|
|
await role_api.delete_role(mgr_role_id)
|
|
test_data_manager._roles.remove(mgr_role_id)
|
|
await role_api.delete_role(emp_role_id)
|
|
test_data_manager._roles.remove(emp_role_id)
|
|
|
|
async def test_bs_organization_restructure(
|
|
self, authenticated_client, test_data_manager
|
|
):
|
|
"""
|
|
BS-04: 组织架构调整流程
|
|
|
|
业务场景:
|
|
1. 创建新部门
|
|
2. 批量调整员工部门
|
|
3. 调整部门权限
|
|
4. 验证组织架构变更
|
|
|
|
验收标准:
|
|
- 部门创建成功
|
|
- 员工部门调整成功
|
|
- 权限调整成功
|
|
- 组织架构更新正确
|
|
"""
|
|
user_api = UserAPI(authenticated_client)
|
|
role_api = RoleAPI(authenticated_client)
|
|
|
|
unique_id = f"org_{int(time.time() * 1000)}_{uuid.uuid4().hex[:8]}"
|
|
|
|
dept_role_data = {
|
|
"roleName": f"新部门角色_{unique_id}",
|
|
"roleKey": f"new_dept_role_{unique_id}",
|
|
"roleSort": 8,
|
|
"status": 1,
|
|
"remark": "业务场景测试-新部门"
|
|
}
|
|
role_response = await role_api.create_role(dept_role_data)
|
|
assert role_response.status_code == 201
|
|
role_id = role_response.json()["id"]
|
|
test_data_manager.add_role(role_id)
|
|
|
|
users_to_create = []
|
|
for i in range(3):
|
|
user_data = {
|
|
"username": f"org_user_{i}_{unique_id}",
|
|
"password": "Test123!@#",
|
|
"email": f"org_user_{i}_{unique_id}@company.com",
|
|
"roleId": role_id,
|
|
"status": 1
|
|
}
|
|
user_response = await user_api.create_user(user_data)
|
|
assert user_response.status_code == 201
|
|
user_id = user_response.json()["id"]
|
|
test_data_manager.add_user(user_id)
|
|
users_to_create.append(user_id)
|
|
|
|
assert len(users_to_create) == 3, "应创建3个用户"
|
|
|
|
for user_id in users_to_create:
|
|
await user_api.delete_user(user_id)
|
|
test_data_manager._users.remove(user_id)
|
|
|
|
await role_api.delete_role(role_id)
|
|
test_data_manager._roles.remove(role_id)
|
|
|
|
async def test_bs_system_config_change(
|
|
self, authenticated_client, test_data_manager
|
|
):
|
|
"""
|
|
BS-05: 系统配置变更流程
|
|
|
|
业务场景:
|
|
1. 修改系统配置
|
|
2. 验证配置生效
|
|
3. 配置回滚
|
|
4. 验证回滚生效
|
|
|
|
验收标准:
|
|
- 配置修改成功
|
|
- 新配置立即生效
|
|
- 回滚操作成功
|
|
- 回滚后配置正确
|
|
"""
|
|
config_api = ConfigAPI(authenticated_client)
|
|
|
|
unique_id = f"config_{int(time.time() * 1000)}_{uuid.uuid4().hex[:8]}"
|
|
|
|
config_data = {
|
|
"configKey": f"test_config_{unique_id}",
|
|
"configName": f"测试配置_{unique_id}",
|
|
"configType": "Y",
|
|
"configValue": "initial_value",
|
|
"remark": "业务场景测试-初始配置"
|
|
}
|
|
create_response = await config_api.create_config(config_data)
|
|
assert create_response.status_code == 201
|
|
config_id = create_response.json()["id"]
|
|
test_data_manager.add_config(config_id)
|
|
|
|
get_response = await config_api.get_config_by_key(f"test_config_{unique_id}")
|
|
assert get_response.status_code == 200
|
|
assert get_response.json()["configValue"] == "initial_value"
|
|
|
|
update_data = {
|
|
"configValue": "updated_value",
|
|
"remark": "业务场景测试-更新配置"
|
|
}
|
|
update_response = await config_api.update_config(config_id, update_data)
|
|
assert update_response.status_code == 200, "配置更新失败"
|
|
|
|
verify_response = await config_api.get_config_by_key(f"test_config_{unique_id}")
|
|
assert verify_response.json()["configValue"] == "updated_value", "配置更新未生效"
|
|
|
|
rollback_data = {
|
|
"configValue": "initial_value",
|
|
"remark": "业务场景测试-配置回滚"
|
|
}
|
|
rollback_response = await config_api.update_config(config_id, rollback_data)
|
|
assert rollback_response.status_code == 200, "配置回滚失败"
|
|
|
|
final_response = await config_api.get_config_by_key(f"test_config_{unique_id}")
|
|
assert final_response.json()["configValue"] == "initial_value", "配置回滚未生效"
|
|
|
|
await config_api.delete_config(config_id)
|
|
test_data_manager._configs.remove(config_id)
|
|
|
|
async def test_bs_audit_trail_verification(
|
|
self, authenticated_client, test_data_manager
|
|
):
|
|
"""
|
|
BS-06: 审计日志验证流程
|
|
|
|
业务场景:
|
|
1. 执行关键操作
|
|
2. 查询审计日志
|
|
3. 验证日志完整性
|
|
4. 导出审计日志
|
|
|
|
验收标准:
|
|
- 操作被记录
|
|
- 日志信息完整
|
|
- 日志可查询
|
|
- 日志可导出
|
|
"""
|
|
user_api = UserAPI(authenticated_client)
|
|
audit_api = AuditAPI(authenticated_client)
|
|
|
|
unique_id = f"audit_{int(time.time() * 1000)}_{uuid.uuid4().hex[:8]}"
|
|
|
|
user_data = {
|
|
"username": f"audit_user_{unique_id}",
|
|
"password": "Test123!@#",
|
|
"email": f"audit_{unique_id}@company.com",
|
|
"status": 1
|
|
}
|
|
create_response = await user_api.create_user(user_data)
|
|
assert create_response.status_code == 201
|
|
user_id = create_response.json()["id"]
|
|
test_data_manager.add_user(user_id)
|
|
|
|
await asyncio.sleep(1)
|
|
|
|
audit_response = await audit_api.get_audit_logs(
|
|
page=0,
|
|
size=10,
|
|
module="用户管理",
|
|
operation="创建用户"
|
|
)
|
|
assert audit_response.status_code == 200, "查询审计日志失败"
|
|
|
|
audit_logs = audit_response.json()
|
|
assert len(audit_logs) > 0, "应存在审计日志"
|
|
|
|
latest_log = audit_logs[0]
|
|
assert "operation" in latest_log, "日志应包含操作类型"
|
|
assert "operator" in latest_log, "日志应包含操作人"
|
|
assert "timestamp" in latest_log, "日志应包含时间戳"
|
|
|
|
await user_api.delete_user(user_id)
|
|
test_data_manager._users.remove(user_id)
|
|
|
|
|
|
@pytest.mark.uat
|
|
@pytest.mark.business_scenario
|
|
@pytest.mark.regression
|
|
class TestBusinessScenarioRegression:
|
|
"""业务场景回归测试"""
|
|
|
|
@pytest.fixture
|
|
async def authenticated_client(self):
|
|
async with AuthAPI.create_client() as client:
|
|
auth_api = AuthAPI(client)
|
|
await auth_api.login(settings.TEST_USERNAME, settings.TEST_PASSWORD)
|
|
yield client
|
|
|
|
@pytest.fixture
|
|
async def test_data_manager(self):
|
|
from utils.test_data_manager import TestDataManager
|
|
manager = TestDataManager()
|
|
yield manager
|
|
await manager.cleanup_all()
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_bs_concurrent_user_operations(
|
|
self, authenticated_client, test_data_manager
|
|
):
|
|
"""
|
|
BS-REG-01: 并发用户操作测试
|
|
|
|
验证点:
|
|
- 多用户并发创建
|
|
- 数据一致性
|
|
- 无死锁
|
|
"""
|
|
user_api = UserAPI(authenticated_client)
|
|
|
|
unique_id = f"concurrent_{int(time.time() * 1000)}"
|
|
|
|
async def create_user(index: int):
|
|
user_data = {
|
|
"username": f"concurrent_user_{index}_{unique_id}",
|
|
"password": "Test123!@#",
|
|
"email": f"concurrent_{index}_{unique_id}@company.com",
|
|
"status": 1
|
|
}
|
|
response = await user_api.create_user(user_data)
|
|
return response
|
|
|
|
tasks = [create_user(i) for i in range(5)]
|
|
results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
|
|
success_count = sum(1 for r in results if not isinstance(r, Exception) and r.status_code == 201)
|
|
assert success_count >= 3, f"至少应有3个用户创建成功,实际: {success_count}"
|
|
|
|
for result in results:
|
|
if not isinstance(result, Exception) and result.status_code == 201:
|
|
user_id = result.json()["id"]
|
|
await user_api.delete_user(user_id)
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_bs_data_consistency(
|
|
self, authenticated_client, test_data_manager
|
|
):
|
|
"""
|
|
BS-REG-02: 数据一致性测试
|
|
|
|
验证点:
|
|
- 创建后立即查询
|
|
- 数据一致性
|
|
"""
|
|
user_api = UserAPI(authenticated_client)
|
|
|
|
unique_id = f"consistency_{int(time.time() * 1000)}"
|
|
|
|
user_data = {
|
|
"username": f"consistency_user_{unique_id}",
|
|
"password": "Test123!@#",
|
|
"email": f"consistency_{unique_id}@company.com",
|
|
"status": 1
|
|
}
|
|
create_response = await user_api.create_user(user_data)
|
|
assert create_response.status_code == 201
|
|
user_id = create_response.json()["id"]
|
|
test_data_manager.add_user(user_id)
|
|
|
|
get_response = await user_api.get_user_by_id(user_id)
|
|
assert get_response.status_code == 200
|
|
|
|
created_user = create_response.json()
|
|
fetched_user = get_response.json()
|
|
|
|
assert created_user["username"] == fetched_user["username"], "用户名应一致"
|
|
assert created_user["email"] == fetched_user["email"], "邮箱应一致"
|
|
|
|
await user_api.delete_user(user_id)
|
|
test_data_manager._users.remove(user_id)
|