Files
gym-manage/test-suite/run_tests.py
T

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()