1e3dc11d59
feat(test-suite): 新增测试套件模块,包含API测试客户端和测试配置 fix(api): 修复数据库实体和仓库的删除操作返回值 style(api): 统一数据库表名和字段命名 perf(api): 添加缓存注解提升配置查询性能 test(api): 添加H2测试数据库配置支持 chore: 清理旧的测试文件和脚本
239 lines
5.5 KiB
Python
239 lines
5.5 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
E2E/UAT 测试启动脚本
|
|
|
|
用于启动整个后台系统的端到端测试和用户验收测试
|
|
支持在开发环境直接运行,无需 Docker 部署
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import subprocess
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
|
|
def parse_args():
|
|
"""解析命令行参数"""
|
|
parser = argparse.ArgumentParser(description='E2E/UAT 测试启动脚本')
|
|
|
|
parser.add_argument(
|
|
'--env',
|
|
type=str,
|
|
default='dev',
|
|
choices=['dev', 'test', 'prod'],
|
|
help='运行环境 (默认: dev)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--database',
|
|
type=str,
|
|
default='h2',
|
|
choices=['h2', 'postgresql'],
|
|
help='测试数据库类型 (默认: h2)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--backend-url',
|
|
type=str,
|
|
default='http://localhost:8084',
|
|
help='后端服务地址 (默认: http://localhost:8084)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--frontend-url',
|
|
type=str,
|
|
default='http://localhost:3000',
|
|
help='前端服务地址 (默认: http://localhost:3000)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--test-dir',
|
|
type=str,
|
|
default='test-suite/api',
|
|
help='测试目录路径 (默认: test-suite/api)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--test-case',
|
|
type=str,
|
|
default=None,
|
|
help='指定要运行的测试用例文件或类 (默认: 运行所有测试)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--parallel',
|
|
action='store_true',
|
|
help='启用并行测试'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--reruns',
|
|
type=int,
|
|
default=0,
|
|
help='失败用例重跑次数 (默认: 0)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--html-report',
|
|
type=str,
|
|
default='test-suite/report.html',
|
|
help='HTML 测试报告路径 (默认: test-suite/report.html)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--junit-report',
|
|
type=str,
|
|
default='test-suite/junit.xml',
|
|
help='JUnit 测试报告路径 (默认: test-suite/junit.xml)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--verbose',
|
|
action='store_true',
|
|
help='启用详细输出模式'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--coverage',
|
|
action='store_true',
|
|
help='启用代码覆盖率报告'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--dry-run',
|
|
action='store_true',
|
|
help='仅打印命令,不实际执行'
|
|
)
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
def check_dependencies():
|
|
"""检查依赖是否安装"""
|
|
required_packages = [
|
|
'pytest',
|
|
'pytest-html',
|
|
'pytest-rerunfailures',
|
|
'pytest-asyncio',
|
|
'requests',
|
|
'pytest-dependency'
|
|
]
|
|
|
|
missing_packages = []
|
|
for package in required_packages:
|
|
try:
|
|
__import__(package.replace('-', '_'))
|
|
except ImportError:
|
|
missing_packages.append(package)
|
|
|
|
if missing_packages:
|
|
print("❌ 缺少必要的 Python 包,请运行:")
|
|
print(f" pip install {' '.join(missing_packages)}")
|
|
sys.exit(1)
|
|
|
|
|
|
def setup_environment(args):
|
|
"""设置环境变量"""
|
|
env_vars = {
|
|
'ENV': args.env,
|
|
'DATABASE': args.database,
|
|
'BASE_URL': args.backend_url,
|
|
'FRONTEND_URL': args.frontend_url,
|
|
'TEST_MODE': 'true'
|
|
}
|
|
|
|
for key, value in env_vars.items():
|
|
os.environ[key] = value
|
|
|
|
print(f"✅ 环境变量已设置:")
|
|
for key, value in env_vars.items():
|
|
print(f" {key}={value}")
|
|
|
|
|
|
def run_pytest(args):
|
|
"""运行 pytest 测试"""
|
|
cmd = [
|
|
sys.executable,
|
|
'-m',
|
|
'pytest',
|
|
args.test_dir,
|
|
f'--html={args.html_report}',
|
|
f'--junitxml={args.junit_report}',
|
|
'--self-contained-html'
|
|
]
|
|
|
|
if args.verbose:
|
|
cmd.append('-v')
|
|
|
|
if args.parallel:
|
|
cmd.extend(['-n', 'auto'])
|
|
|
|
if args.reruns > 0:
|
|
cmd.extend(['--reruns', str(args.reruns)])
|
|
|
|
if args.test_case:
|
|
cmd.append(args.test_case)
|
|
|
|
if args.coverage:
|
|
cmd.extend([
|
|
'--cov=test_suite',
|
|
'--cov-report=html:test-suite/coverage',
|
|
'--cov-report=term'
|
|
])
|
|
|
|
print(f"\n🚀 运行测试命令:")
|
|
print(f" {' '.join(cmd)}\n")
|
|
|
|
if args.dry_run:
|
|
print("✅ 干运行模式,测试未执行")
|
|
return 0
|
|
|
|
result = subprocess.run(cmd)
|
|
return result.returncode
|
|
|
|
|
|
def main():
|
|
"""主函数"""
|
|
args = parse_args()
|
|
|
|
print("=" * 60)
|
|
print("🔧 E2E/UAT 测试启动脚本")
|
|
print("=" * 60)
|
|
|
|
# 检查依赖
|
|
print("\n📦 检查依赖...")
|
|
check_dependencies()
|
|
print("✅ 依赖检查通过")
|
|
|
|
# 设置环境
|
|
print("\n⚙️ 设置环境...")
|
|
setup_environment(args)
|
|
|
|
# 运行测试
|
|
print("\n🧪 运行测试...")
|
|
exit_code = run_pytest(args)
|
|
|
|
# 输出结果
|
|
print("\n" + "=" * 60)
|
|
if exit_code == 0:
|
|
print("✅ 测试全部通过!")
|
|
else:
|
|
print(f"❌ 测试失败 (退出码: {exit_code})")
|
|
print("=" * 60)
|
|
|
|
# 输出报告路径
|
|
print(f"\n📊 测试报告:")
|
|
print(f" HTML: file://{os.path.abspath(args.html_report)}")
|
|
print(f" JUnit: {os.path.abspath(args.junit_report)}")
|
|
|
|
if args.coverage:
|
|
print(f" Coverage: file://{os.path.abspath('test-suite/coverage/index.html')}")
|
|
|
|
sys.exit(exit_code)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|