f14002559e
refactor(components): 调整头部和页脚布局样式 style(hero-section): 更新徽章动画效果 docs: 添加测试框架README文档 test: 实现首页、导航和联系表单的测试用例 ci: 添加CI测试脚本和配置
282 lines
8.2 KiB
Python
282 lines
8.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
CI/CD 测试脚本
|
|
用于持续集成环境中的测试执行
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import json
|
|
import time
|
|
from pathlib import Path
|
|
from datetime import datetime
|
|
|
|
# 添加项目路径
|
|
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
|
|
|
|
|
|
class CITestRunner:
|
|
"""CI测试运行器"""
|
|
|
|
def __init__(self):
|
|
self.logger = get_logger()
|
|
self.settings = get_settings()
|
|
self.results = {
|
|
"timestamp": datetime.now().isoformat(),
|
|
"environment": os.environ.get("ENVIRONMENT", "development"),
|
|
"browser": os.environ.get("PLAYWRIGHT_BROWSER", "chromium"),
|
|
"tests": [],
|
|
"summary": {
|
|
"total": 0,
|
|
"passed": 0,
|
|
"failed": 0,
|
|
"skipped": 0,
|
|
"error": 0,
|
|
"duration": 0
|
|
}
|
|
}
|
|
|
|
def run_smoke_tests(self) -> bool:
|
|
"""运行冒烟测试"""
|
|
self.logger.section("运行冒烟测试")
|
|
|
|
from playwright.sync_api import sync_playwright
|
|
import pytest
|
|
|
|
pytest_args = [
|
|
"-c", str(project_root / "pytest.ini"),
|
|
"-m", "smoke",
|
|
"-v",
|
|
"--tb=short",
|
|
"--json-report",
|
|
"--json-report-file=reports/smoke_test_results.json",
|
|
"tests"
|
|
]
|
|
|
|
try:
|
|
exit_code = pytest.main(pytest_args)
|
|
return exit_code == 0
|
|
except Exception as e:
|
|
self.logger.error(f"冒烟测试失败: {e}")
|
|
return False
|
|
|
|
def run_regression_tests(self) -> bool:
|
|
"""运行回归测试"""
|
|
self.logger.section("运行回归测试")
|
|
|
|
import pytest
|
|
|
|
pytest_args = [
|
|
"-c", str(project_root / "pytest.ini"),
|
|
"-m", "regression",
|
|
"-v",
|
|
"--tb=short",
|
|
"--json-report",
|
|
"--json-report-file=reports/regression_test_results.json",
|
|
"tests"
|
|
]
|
|
|
|
try:
|
|
exit_code = pytest.main(pytest_args)
|
|
return exit_code == 0
|
|
except Exception as e:
|
|
self.logger.error(f"回归测试失败: {e}")
|
|
return False
|
|
|
|
def run_performance_tests(self) -> bool:
|
|
"""运行性能测试"""
|
|
self.logger.section("运行性能测试")
|
|
|
|
import pytest
|
|
|
|
pytest_args = [
|
|
"-c", str(project_root / "pytest.ini"),
|
|
"-m", "performance",
|
|
"-v",
|
|
"--tb=short",
|
|
"--json-report",
|
|
"--json-report-file=reports/performance_test_results.json",
|
|
"tests"
|
|
]
|
|
|
|
try:
|
|
exit_code = pytest.main(pytest_args)
|
|
return exit_code == 0
|
|
except Exception as e:
|
|
self.logger.error(f"性能测试失败: {e}")
|
|
return False
|
|
|
|
def run_cross_browser_tests(self) -> dict:
|
|
"""运行跨浏览器测试"""
|
|
self.logger.section("运行跨浏览器测试")
|
|
|
|
import pytest
|
|
browsers = ["chromium", "firefox", "webkit"]
|
|
results = {}
|
|
|
|
for browser in browsers:
|
|
self.logger.info(f"测试浏览器: {browser}")
|
|
|
|
os.environ["PLAYWRIGHT_BROWSER"] = browser
|
|
|
|
pytest_args = [
|
|
"-c", str(project_root / "pytest.ini"),
|
|
"-m", "smoke",
|
|
"-v",
|
|
"--tb=short",
|
|
f"--json-report=reports/{browser}_test_results.json",
|
|
"tests"
|
|
]
|
|
|
|
try:
|
|
exit_code = pytest.main(pytest_args)
|
|
results[browser] = exit_code == 0
|
|
except Exception as e:
|
|
self.logger.error(f"{browser} 测试失败: {e}")
|
|
results[browser] = False
|
|
|
|
return results
|
|
|
|
def run_full_test_suite(self) -> bool:
|
|
"""运行完整测试套件"""
|
|
self.logger.section("运行完整测试套件")
|
|
|
|
import pytest
|
|
|
|
pytest_args = [
|
|
"-c", str(project_root / "pytest.ini"),
|
|
"-v",
|
|
"--tb=short",
|
|
"--json-report",
|
|
"--json-report-file=reports/full_test_results.json",
|
|
"--html=reports/full_test_report.html",
|
|
"--self-contained-html",
|
|
"tests"
|
|
]
|
|
|
|
try:
|
|
exit_code = pytest.main(pytest_args)
|
|
return exit_code == 0
|
|
except Exception as e:
|
|
self.logger.error(f"完整测试失败: {e}")
|
|
return False
|
|
|
|
def generate_ci_report(self, test_results: dict):
|
|
"""生成CI测试报告"""
|
|
report_path = Path("reports/ci_test_report.json")
|
|
report_path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
with open(report_path, "w", encoding="utf-8") as f:
|
|
json.dump(test_results, f, indent=2, ensure_ascii=False)
|
|
|
|
self.logger.info(f"CI报告已生成: {report_path}")
|
|
|
|
def run_ci_tests(self, test_type: str = "full"):
|
|
"""运行CI测试"""
|
|
start_time = time.time()
|
|
|
|
self.logger.section("开始 CI 测试")
|
|
self.logger.info(f"环境: {self.results['environment']}")
|
|
self.logger.info(f"浏览器: {self.results['browser']}")
|
|
self.logger.info(f"测试类型: {test_type}")
|
|
|
|
success = False
|
|
|
|
if test_type == "smoke":
|
|
success = self.run_smoke_tests()
|
|
elif test_type == "regression":
|
|
success = self.run_regression_tests()
|
|
elif test_type == "performance":
|
|
success = self.run_performance_tests()
|
|
elif test_type == "cross_browser":
|
|
cross_results = self.run_cross_browser_tests()
|
|
success = all(cross_results.values())
|
|
self.results["cross_browser_results"] = cross_results
|
|
elif test_type == "full":
|
|
success = self.run_full_test_suite()
|
|
else:
|
|
self.logger.error(f"未知的测试类型: {test_type}")
|
|
return False
|
|
|
|
end_time = time.time()
|
|
self.results["summary"]["duration"] = end_time - start_time
|
|
self.results["success"] = success
|
|
|
|
self.logger.section("CI 测试完成")
|
|
self.logger.info(f"总耗时: {self.results['summary']['duration']:.2f}秒")
|
|
self.logger.info(f"测试结果: {'成功' if success else '失败'}")
|
|
|
|
# 生成报告
|
|
self.generate_ci_report(self.results)
|
|
|
|
return success
|
|
|
|
|
|
def parse_ci_arguments():
|
|
"""解析CI参数"""
|
|
parser = argparse.ArgumentParser(
|
|
description="Novalon Website CI 测试运行器"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--test-type",
|
|
default="full",
|
|
choices=["smoke", "regression", "performance", "cross_browser", "full"],
|
|
help="测试类型 (默认: full)"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--env",
|
|
default="development",
|
|
choices=["development", "staging", "production"],
|
|
help="测试环境 (默认: development)"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--browser",
|
|
default="chromium",
|
|
choices=["chromium", "firefox", "webkit", "all"],
|
|
help="浏览器 (默认: chromium)"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--report-dir",
|
|
default="reports",
|
|
help="报告目录 (默认: reports)"
|
|
)
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
def main():
|
|
"""CI主函数"""
|
|
args = parse_ci_arguments()
|
|
|
|
# 设置环境变量
|
|
os.environ["ENVIRONMENT"] = args.env
|
|
os.environ["PLAYWRIGHT_BROWSER"] = args.browser
|
|
os.environ["REPORT_DIR"] = args.report_dir
|
|
|
|
# 确保报告目录存在
|
|
Path(args.report_dir).mkdir(parents=True, exist_ok=True)
|
|
|
|
# 运行测试
|
|
runner = CITestRunner()
|
|
success = runner.run_ci_tests(args.test_type)
|
|
|
|
# 输出结果
|
|
if success:
|
|
print("\n✅ CI 测试通过")
|
|
sys.exit(0)
|
|
else:
|
|
print("\n❌ CI 测试失败")
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|