6392c08560
refactor(db): 重构查询条件类到query目录下 test: 添加登录流程测试脚本和测试数据 chore: 添加crypto-js依赖用于签名验证 ci: 配置测试环境数据库和端口设置
363 lines
11 KiB
Python
363 lines
11 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Novalon管理系统全面业务流程测试
|
|
测试所有核心业务流程
|
|
"""
|
|
|
|
import time
|
|
import json
|
|
from datetime import datetime
|
|
from playwright.sync_api import sync_playwright, Page, expect
|
|
|
|
class TestResult:
|
|
def __init__(self):
|
|
self.total = 0
|
|
self.passed = 0
|
|
self.failed = 0
|
|
self.errors = []
|
|
self.start_time = datetime.now()
|
|
|
|
def add_pass(self, test_name):
|
|
self.total += 1
|
|
self.passed += 1
|
|
print(f"✅ {test_name} - 通过")
|
|
|
|
def add_fail(self, test_name, error):
|
|
self.total += 1
|
|
self.failed += 1
|
|
self.errors.append({"test": test_name, "error": str(error)})
|
|
print(f"❌ {test_name} - 失败: {error}")
|
|
|
|
def print_summary(self):
|
|
duration = (datetime.now() - self.start_time).total_seconds()
|
|
print("\n" + "="*80)
|
|
print("测试总结")
|
|
print("="*80)
|
|
print(f"总测试数: {self.total}")
|
|
print(f"通过: {self.passed} ✅")
|
|
print(f"失败: {self.failed} ❌")
|
|
print(f"成功率: {(self.passed/self.total*100):.2f}%")
|
|
print(f"耗时: {duration:.2f}秒")
|
|
|
|
if self.errors:
|
|
print("\n失败详情:")
|
|
for error in self.errors:
|
|
print(f" - {error['test']}: {error['error']}")
|
|
print("="*80)
|
|
|
|
result = TestResult()
|
|
|
|
def login(page: Page, username: str = "admin", password: str = "Test@123"):
|
|
"""登录系统"""
|
|
try:
|
|
page.goto("http://localhost:3002/login")
|
|
page.wait_for_load_state("networkidle")
|
|
|
|
page.fill('input[placeholder*="用户名"]', username)
|
|
page.fill('input[placeholder*="密码"]', password)
|
|
page.click('button:has-text("登录")')
|
|
|
|
page.wait_for_url("**/dashboard", timeout=10000)
|
|
page.wait_for_load_state("networkidle")
|
|
|
|
return True
|
|
except Exception as e:
|
|
print(f"登录失败: {e}")
|
|
return False
|
|
|
|
def test_user_management_flow(page: Page):
|
|
"""测试用户管理完整流程"""
|
|
print("\n📋 测试用户管理流程...")
|
|
|
|
try:
|
|
# 导航到用户管理页面
|
|
page.click('text=用户管理')
|
|
page.wait_for_load_state("networkidle")
|
|
time.sleep(1)
|
|
|
|
# 测试创建用户
|
|
print(" - 测试创建用户...")
|
|
page.click('button:has-text("新增")')
|
|
time.sleep(0.5)
|
|
|
|
page.fill('input[placeholder*="用户名"]', f"testuser_{int(time.time())}")
|
|
page.fill('input[placeholder*="密码"]', "admin123")
|
|
page.fill('input[placeholder*="邮箱"]', f"test_{int(time.time())}@example.com")
|
|
page.fill('input[placeholder*="手机"]', "13800138000")
|
|
page.fill('input[placeholder*="昵称"]', "测试用户")
|
|
|
|
page.click('button:has-text("确定")')
|
|
time.sleep(1)
|
|
|
|
result.add_pass("用户管理-创建用户")
|
|
|
|
except Exception as e:
|
|
result.add_fail("用户管理-创建用户", e)
|
|
|
|
def test_role_management_flow(page: Page):
|
|
"""测试角色管理完整流程"""
|
|
print("\n📋 测试角色管理流程...")
|
|
|
|
try:
|
|
# 导航到角色管理页面
|
|
page.click('text=角色管理')
|
|
page.wait_for_load_state("networkidle")
|
|
time.sleep(1)
|
|
|
|
# 测试创建角色
|
|
print(" - 测试创建角色...")
|
|
page.click('button:has-text("新增")')
|
|
time.sleep(0.5)
|
|
|
|
page.fill('input[placeholder*="角色名称"]', f"测试角色_{int(time.time())}")
|
|
page.fill('input[placeholder*="角色标识"]', f"test_role_{int(time.time())}")
|
|
|
|
page.click('button:has-text("确定")')
|
|
time.sleep(1)
|
|
|
|
result.add_pass("角色管理-创建角色")
|
|
|
|
except Exception as e:
|
|
result.add_fail("角色管理-创建角色", e)
|
|
|
|
def test_menu_management_flow(page: Page):
|
|
"""测试菜单管理完整流程"""
|
|
print("\n📋 测试菜单管理流程...")
|
|
|
|
try:
|
|
# 导航到菜单管理页面
|
|
page.click('text=菜单管理')
|
|
page.wait_for_load_state("networkidle")
|
|
time.sleep(1)
|
|
|
|
# 测试创建菜单
|
|
print(" - 测试创建菜单...")
|
|
page.click('button:has-text("新增")')
|
|
time.sleep(0.5)
|
|
|
|
page.fill('input[placeholder*="菜单名称"]', f"测试菜单_{int(time.time())}")
|
|
page.select_option('select', 'C')
|
|
|
|
page.click('button:has-text("确定")')
|
|
time.sleep(1)
|
|
|
|
result.add_pass("菜单管理-创建菜单")
|
|
|
|
except Exception as e:
|
|
result.add_fail("菜单管理-创建菜单", e)
|
|
|
|
def test_dictionary_management_flow(page: Page):
|
|
"""测试字典管理完整流程"""
|
|
print("\n📋 测试字典管理流程...")
|
|
|
|
try:
|
|
# 导航到字典管理页面
|
|
page.click('text=字典管理')
|
|
page.wait_for_load_state("networkidle")
|
|
time.sleep(1)
|
|
|
|
# 测试查询字典
|
|
print(" - 测试查询字典...")
|
|
page.fill('input[placeholder*="搜索"]', "用户状态")
|
|
page.press('input[placeholder*="搜索"]', 'Enter')
|
|
time.sleep(1)
|
|
|
|
result.add_pass("字典管理-查询字典")
|
|
|
|
except Exception as e:
|
|
result.add_fail("字典管理-查询字典", e)
|
|
|
|
def test_system_config_flow(page: Page):
|
|
"""测试系统配置流程"""
|
|
print("\n📋 测试系统配置流程...")
|
|
|
|
try:
|
|
# 导航到系统配置页面
|
|
page.click('text=系统配置')
|
|
page.wait_for_load_state("networkidle")
|
|
time.sleep(1)
|
|
|
|
# 测试查询配置
|
|
print(" - 测试查询配置...")
|
|
page.fill('input[placeholder*="搜索"]', "用户")
|
|
page.press('input[placeholder*="搜索"]', 'Enter')
|
|
time.sleep(1)
|
|
|
|
result.add_pass("系统配置-查询配置")
|
|
|
|
except Exception as e:
|
|
result.add_fail("系统配置-查询配置", e)
|
|
|
|
def test_file_management_flow(page: Page):
|
|
"""测试文件管理流程"""
|
|
print("\n📋 测试文件管理流程...")
|
|
|
|
try:
|
|
# 导航到文件管理页面
|
|
page.click('text=文件管理')
|
|
page.wait_for_load_state("networkidle")
|
|
time.sleep(1)
|
|
|
|
# 测试查看文件列表
|
|
print(" - 测试查看文件列表...")
|
|
page.wait_for_selector('table', timeout=5000)
|
|
|
|
result.add_pass("文件管理-查看文件列表")
|
|
|
|
except Exception as e:
|
|
result.add_fail("文件管理-查看文件列表", e)
|
|
|
|
def test_notification_flow(page: Page):
|
|
"""测试通知管理流程"""
|
|
print("\n📋 测试通知管理流程...")
|
|
|
|
try:
|
|
# 导航到通知管理页面
|
|
page.click('text=通知公告')
|
|
page.wait_for_load_state("networkidle")
|
|
time.sleep(1)
|
|
|
|
# 测试查看通知列表
|
|
print(" - 测试查看通知列表...")
|
|
page.wait_for_selector('table', timeout=5000)
|
|
|
|
result.add_pass("通知管理-查看通知列表")
|
|
|
|
except Exception as e:
|
|
result.add_fail("通知管理-查看通知列表", e)
|
|
|
|
def test_audit_log_flow(page: Page):
|
|
"""测试审计日志流程"""
|
|
print("\n📋 测试审计日志流程...")
|
|
|
|
try:
|
|
# 导航到操作日志页面
|
|
page.click('text=操作日志')
|
|
page.wait_for_load_state("networkidle")
|
|
time.sleep(1)
|
|
|
|
# 测试查看日志列表
|
|
print(" - 测试查看操作日志...")
|
|
page.wait_for_selector('table', timeout=5000)
|
|
|
|
result.add_pass("审计日志-查看操作日志")
|
|
|
|
# 导航到登录日志页面
|
|
page.click('text=登录日志')
|
|
page.wait_for_load_state("networkidle")
|
|
time.sleep(1)
|
|
|
|
result.add_pass("审计日志-查看登录日志")
|
|
|
|
except Exception as e:
|
|
result.add_fail("审计日志-查看日志", e)
|
|
|
|
def test_permission_validation(page: Page):
|
|
"""测试权限验证"""
|
|
print("\n📋 测试权限验证...")
|
|
|
|
try:
|
|
# 测试菜单权限
|
|
print(" - 测试菜单访问权限...")
|
|
menus = ['用户管理', '角色管理', '菜单管理', '字典管理', '系统配置']
|
|
|
|
for menu in menus:
|
|
try:
|
|
page.click(f'text={menu}')
|
|
page.wait_for_load_state("networkidle")
|
|
time.sleep(0.5)
|
|
result.add_pass(f"权限验证-访问{menu}")
|
|
except:
|
|
result.add_fail(f"权限验证-访问{menu}", "无法访问")
|
|
|
|
except Exception as e:
|
|
result.add_fail("权限验证", e)
|
|
|
|
def test_dashboard(page: Page):
|
|
"""测试仪表板"""
|
|
print("\n📋 测试仪表板...")
|
|
|
|
try:
|
|
# 导航到仪表板
|
|
page.click('text=仪表板')
|
|
page.wait_for_load_state("networkidle")
|
|
time.sleep(1)
|
|
|
|
# 验证仪表板加载
|
|
page.wait_for_selector('.dashboard-container, .stats-card, .chart', timeout=5000)
|
|
|
|
result.add_pass("仪表板-加载成功")
|
|
|
|
except Exception as e:
|
|
result.add_fail("仪表板-加载", e)
|
|
|
|
def main():
|
|
print("="*80)
|
|
print("Novalon管理系统全面业务流程测试")
|
|
print("="*80)
|
|
print(f"测试时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
|
print("="*80)
|
|
|
|
with sync_playwright() as p:
|
|
# 启动浏览器
|
|
browser = p.chromium.launch(headless=True)
|
|
context = browser.new_context()
|
|
page = context.new_page()
|
|
|
|
try:
|
|
# 登录测试
|
|
print("\n🔐 测试登录...")
|
|
if login(page):
|
|
result.add_pass("登录功能")
|
|
print("✅ 登录成功")
|
|
else:
|
|
result.add_fail("登录功能", "登录失败")
|
|
return
|
|
|
|
# 测试仪表板
|
|
test_dashboard(page)
|
|
|
|
# 测试用户管理流程
|
|
test_user_management_flow(page)
|
|
|
|
# 测试角色管理流程
|
|
test_role_management_flow(page)
|
|
|
|
# 测试菜单管理流程
|
|
test_menu_management_flow(page)
|
|
|
|
# 测试字典管理流程
|
|
test_dictionary_management_flow(page)
|
|
|
|
# 测试系统配置流程
|
|
test_system_config_flow(page)
|
|
|
|
# 测试文件管理流程
|
|
test_file_management_flow(page)
|
|
|
|
# 测试通知管理流程
|
|
test_notification_flow(page)
|
|
|
|
# 测试审计日志流程
|
|
test_audit_log_flow(page)
|
|
|
|
# 测试权限验证
|
|
test_permission_validation(page)
|
|
|
|
except Exception as e:
|
|
print(f"\n❌ 测试执行出错: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
|
|
finally:
|
|
browser.close()
|
|
|
|
# 打印测试总结
|
|
result.print_summary()
|
|
|
|
# 返回退出码
|
|
return 0 if result.failed == 0 else 1
|
|
|
|
if __name__ == "__main__":
|
|
exit(main())
|