#!/usr/bin/env python3 """ 测试运行脚本 提供便捷的测试执行命令 """ import os import sys import argparse from pathlib import Path # 添加项目路径 project_root = Path(__file__).parent.parent sys.path.insert(0, str(project_root)) from config.settings import get_settings from utils.logger import get_logger def parse_arguments(): """解析命令行参数""" parser = argparse.ArgumentParser( description="Novalon Website E2E 测试运行器" ) parser.add_argument( "-b", "--browser", default="chromium", choices=["chromium", "firefox", "webkit", "all"], help="指定浏览器 (默认: chromium)" ) parser.add_argument( "-h", "--headless", action="store_true", default=False, help="以无头模式运行 (默认: False)" ) parser.add_argument( "-m", "--marker", default="", help="运行指定标记的测试 (例如: -m smoke)" ) parser.add_argument( "-k", "--keyword", default="", help="运行包含关键字的测试 (例如: -k home)" ) parser.add_argument( "-v", "--verbose", action="store_true", default=False, help="显示详细输出" ) parser.add_argument( "--html", action="store_true", default=False, help="生成HTML测试报告" ) parser.add_argument( "--video", action="store_true", default=False, help="录制测试视频" ) parser.add_argument( "--screenshot", action="store_true", default=False, help="失败时截图" ) parser.add_argument( "--parallel", action="store_true", default=False, help="并行执行测试" ) parser.add_argument( "--workers", type=int, default=4, help="并行工作数 (默认: 4)" ) parser.add_argument( "--report-dir", default="reports", help="报告目录 (默认: reports)" ) parser.add_argument( "--env", default="development", choices=["development", "staging", "production"], help="测试环境 (默认: development)" ) parser.add_argument( "test_paths", nargs="*", default=["tests"], help="测试路径 (默认: tests)" ) return parser.parse_args() def build_pytest_args(args): """构建pytest参数""" pytest_args = [] # 配置文件 pytest_args.append("-c") pytest_args.append(str(project_root / "pytest.ini")) # 浏览器参数 os.environ["PLAYWRIGHT_BROWSER"] = args.browser # 无头模式 if args.headless: os.environ["PLAYWRIGHT_HEADLESS"] = "1" # 标记过滤 if args.marker: pytest_args.append(f"-m={args.marker}") # 关键字过滤 if args.keyword: pytest_args.append(f"-k={args.keyword}") # 详细输出 if args.verbose: pytest_args.append("-v") pytest_args.append("--tb=short") # HTML报告 if args.html: pytest_args.append("--html=reports/test_report.html") pytest_args.append("--self-contained-html") # 视频录制 if args.video: os.environ["PLAYWRIGHT_VIDEO"] = "1" # 失败截图 if args.screenshot: os.environ["PLAYWRIGHT_SCREENSHOT"] = "1" # 并行执行 if args.parallel: pytest_args.append(f"-n={args.workers}") pytest_args.append("--dist=loadscope") # 报告目录 if args.report_dir: pytest_args.append(f"--report-dir={args.report_dir}") # 测试路径 pytest_args.extend(args.test_paths) # 覆盖率(可选) pytest_args.append("--cov=e2e-tests") pytest_args.append("--cov-report=term-missing") return pytest_args def run_tests(args): """运行测试""" logger = get_logger() logger.section("开始 E2E 测试") logger.info(f"浏览器: {args.browser}") logger.info(f"无头模式: {args.headless}") logger.info(f"测试路径: {args.test_paths}") if args.marker: logger.info(f"测试标记: {args.marker}") if args.keyword: logger.info(f"关键字过滤: {args.keyword}") # 构建pytest参数 pytest_args = build_pytest_args(args) # 导入pytest import pytest # 运行测试 exit_code = pytest.main(pytest_args) logger.section("测试运行完成") return exit_code def main(): """主函数""" args = parse_arguments() # 设置环境 os.environ["ENVIRONMENT"] = args.env try: exit_code = run_tests(args) sys.exit(exit_code) except KeyboardInterrupt: print("\n测试被用户中断") sys.exit(130) except Exception as e: print(f"测试运行出错: {e}") sys.exit(1) if __name__ == "__main__": main()