|
|
@@ -0,0 +1,227 @@
|
|
|
+#!/usr/bin/env python3
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
+
|
|
|
+"""
|
|
|
+测试运行脚本
|
|
|
+用于执行项目中的接口测试用例并生成测试报告
|
|
|
+
|
|
|
+使用方法:
|
|
|
+1. 直接运行: python testRun.py
|
|
|
+2. 带参数运行: python testRun.py -m "baidu" -e dev -r allure
|
|
|
+"""
|
|
|
+
|
|
|
+import os
|
|
|
+import sys
|
|
|
+import time
|
|
|
+import argparse
|
|
|
+import subprocess
|
|
|
+import webbrowser
|
|
|
+import json
|
|
|
+import shutil
|
|
|
+from datetime import datetime
|
|
|
+
|
|
|
+# 添加项目根目录到Python路径,确保可以导入项目模块
|
|
|
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
|
+
|
|
|
+def run_tests(test_marker=None, environment=None, report_type="allure"):
|
|
|
+ """
|
|
|
+ 运行测试并生成报告
|
|
|
+ Args:
|
|
|
+ test_marker (str): pytest标记,用于选择特定测试
|
|
|
+ environment (str): 测试环境
|
|
|
+ report_type (str): 报告类型,支持html和allure
|
|
|
+ """
|
|
|
+ # 设置环境变量
|
|
|
+ if environment:
|
|
|
+ os.environ['TEST_ENV'] = environment
|
|
|
+ print(f"设置测试环境: {environment}")
|
|
|
+
|
|
|
+ # 创建报告目录
|
|
|
+ report_dir = os.path.join(os.path.dirname(__file__), 'Reports/API/')
|
|
|
+ if not os.path.exists(report_dir):
|
|
|
+ os.makedirs(report_dir)
|
|
|
+
|
|
|
+ # 构建pytest命令
|
|
|
+ pytest_cmd = [
|
|
|
+ sys.executable, '-m', 'pytest',
|
|
|
+ 'Tests/API/', # 测试目录
|
|
|
+ '-v', # 详细输出
|
|
|
+ '--tb=short', # 短的traceback格式
|
|
|
+ '--alluredir', os.path.join(report_dir, 'allure_results') # 总是生成Allure结果
|
|
|
+ ]
|
|
|
+
|
|
|
+ # 添加标记选择
|
|
|
+ if test_marker:
|
|
|
+ pytest_cmd.extend(['-m', test_marker])
|
|
|
+ print(f"运行标记为 '{test_marker}' 的测试")
|
|
|
+
|
|
|
+ # 记录开始时间
|
|
|
+ start_time = time.time()
|
|
|
+
|
|
|
+ # 运行测试
|
|
|
+ print("\n开始运行测试...")
|
|
|
+ print("命令: " + " ".join(pytest_cmd))
|
|
|
+ print("-" * 50)
|
|
|
+
|
|
|
+ try:
|
|
|
+ # 修复编码问题:使用subprocess.run并指定编码
|
|
|
+ result = subprocess.run(
|
|
|
+ pytest_cmd,
|
|
|
+ capture_output=True,
|
|
|
+ text=True,
|
|
|
+ encoding='utf-8',
|
|
|
+ errors='replace'
|
|
|
+ )
|
|
|
+
|
|
|
+ # 输出测试结果
|
|
|
+ print(result.stdout)
|
|
|
+ if result.stderr:
|
|
|
+ print("错误输出:")
|
|
|
+ print(result.stderr)
|
|
|
+
|
|
|
+ # 计算测试耗时
|
|
|
+ duration = time.time() - start_time
|
|
|
+ minutes, seconds = divmod(duration, 60)
|
|
|
+ print(f"\n测试完成,耗时: {int(minutes)}分{seconds:.2f}秒")
|
|
|
+
|
|
|
+ # 处理报告
|
|
|
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
|
+ report_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
+
|
|
|
+ if report_type == "html":
|
|
|
+ # 生成自定义HTML报告
|
|
|
+ html_report_dir = os.path.join(report_dir, f'html_report_{timestamp}')
|
|
|
+ os.makedirs(html_report_dir, exist_ok=True)
|
|
|
+
|
|
|
+ # 复制模板文件
|
|
|
+ templates_dir = os.path.join(os.path.dirname(__file__), 'templates', 'html')
|
|
|
+ for file in os.listdir(templates_dir):
|
|
|
+ if file.endswith('.html') or file.endswith('.css'):
|
|
|
+ shutil.copy2(
|
|
|
+ os.path.join(templates_dir, file),
|
|
|
+ os.path.join(html_report_dir, file)
|
|
|
+ )
|
|
|
+
|
|
|
+ # 生成测试数据JSON文件
|
|
|
+ generate_html_report_data(
|
|
|
+ result,
|
|
|
+ os.path.join(html_report_dir, 'data.json'),
|
|
|
+ report_time,
|
|
|
+ environment
|
|
|
+ )
|
|
|
+
|
|
|
+ print(f"HTML报告已生成: {html_report_dir}/index.html")
|
|
|
+
|
|
|
+ elif report_type == "allure":
|
|
|
+ # 生成Allure报告
|
|
|
+ allure_report_dir = os.path.join(report_dir, f'allure_report_{timestamp}')
|
|
|
+ allure_cmd = [
|
|
|
+ 'allure', 'generate',
|
|
|
+ os.path.join(report_dir, 'allure_results'),
|
|
|
+ '-o', allure_report_dir,
|
|
|
+ '--clean'
|
|
|
+ ]
|
|
|
+ print(f"\n生成Allure报告: {' '.join(allure_cmd)}")
|
|
|
+ subprocess.run(allure_cmd, check=True)
|
|
|
+
|
|
|
+ # 复制自定义CSS
|
|
|
+ css_src = os.path.join(os.path.dirname(__file__), 'templates', 'allure', 'custom.css')
|
|
|
+ css_dest = os.path.join(allure_report_dir, 'plugins', 'custom-css', 'css', 'custom.css')
|
|
|
+ if os.path.exists(css_src):
|
|
|
+ os.makedirs(os.path.dirname(css_dest), exist_ok=True)
|
|
|
+ shutil.copy2(css_src, css_dest)
|
|
|
+
|
|
|
+ # 打开Allure报告
|
|
|
+ index_html = os.path.join(allure_report_dir, 'index.html')
|
|
|
+ if os.path.exists(index_html):
|
|
|
+ print(f"打开报告: {index_html}")
|
|
|
+ webbrowser.open(f'file://{os.path.abspath(index_html)}')
|
|
|
+
|
|
|
+ # 返回测试结果
|
|
|
+ return result.returncode
|
|
|
+
|
|
|
+ except (subprocess.CalledProcessError, FileNotFoundError) as e:
|
|
|
+ print(f"生成报告失败: {e}")
|
|
|
+ if "allure" in str(e):
|
|
|
+ print("请确保已安装Allure命令行工具")
|
|
|
+ return 1
|
|
|
+ except Exception as e:
|
|
|
+ print(f"运行测试时发生错误: {e}")
|
|
|
+ return 1
|
|
|
+
|
|
|
+
|
|
|
+def generate_html_report_data(result, output_path, report_time, environment):
|
|
|
+ """生成HTML报告所需的数据"""
|
|
|
+ # 解析测试结果(简化版)
|
|
|
+ # 在实际应用中,您可能需要解析pytest的JSON报告或Allure结果
|
|
|
+ summary = {
|
|
|
+ "total": 0,
|
|
|
+ "passed": 0,
|
|
|
+ "failed": 0,
|
|
|
+ "skipped": 0,
|
|
|
+ "duration": "0s",
|
|
|
+ "success_rate": 0
|
|
|
+ }
|
|
|
+
|
|
|
+ tests = []
|
|
|
+
|
|
|
+ # 这里只是示例,实际应用中需要解析真实的测试结果
|
|
|
+ # 您可以使用pytest-json-report插件来获取JSON格式的测试结果
|
|
|
+ summary["total"] = 2
|
|
|
+ summary["passed"] = 0
|
|
|
+ summary["failed"] = 2
|
|
|
+ summary["skipped"] = 0
|
|
|
+ summary["duration"] = "3.61s"
|
|
|
+ summary["success_rate"] = 0
|
|
|
+
|
|
|
+ tests.append({
|
|
|
+ "name": "TestBaiduAPI::test_baidu_search",
|
|
|
+ "status": "failed",
|
|
|
+ "duration": "2.1s",
|
|
|
+ "error": "AssertionError: assert 'python接口测试' in '<!DOCTYPE html>...'"
|
|
|
+ })
|
|
|
+
|
|
|
+ tests.append({
|
|
|
+ "name": "TestBaiduAPI::test_baidu_homepage",
|
|
|
+ "status": "failed",
|
|
|
+ "duration": "1.5s",
|
|
|
+ "error": "AssertionError: assert '百度一下' in '<!DOCTYPE html>...'"
|
|
|
+ })
|
|
|
+
|
|
|
+ # 保存数据到JSON文件
|
|
|
+ data = {
|
|
|
+ "summary": summary,
|
|
|
+ "tests": tests,
|
|
|
+ "report_time": report_time,
|
|
|
+ "environment": environment
|
|
|
+ }
|
|
|
+
|
|
|
+ with open(output_path, 'w', encoding='utf-8') as f:
|
|
|
+ json.dump(data, f, ensure_ascii=False, indent=2)
|
|
|
+
|
|
|
+
|
|
|
+def main():
|
|
|
+ """主函数,解析命令行参数并运行测试"""
|
|
|
+ # 创建参数解析器
|
|
|
+ parser = argparse.ArgumentParser(description='运行接口测试')
|
|
|
+ parser.add_argument('-m', '--marker', help='运行指定标记的测试,如 "baidu"')
|
|
|
+ parser.add_argument('-e', '--env', help='测试环境,如 "dev", "prod", "baidu"')
|
|
|
+ parser.add_argument('-r', '--report', choices=['html', 'allure'],
|
|
|
+ default='allure', help='报告类型,默认allure')
|
|
|
+
|
|
|
+ # 解析参数
|
|
|
+ args = parser.parse_args()
|
|
|
+
|
|
|
+ # 运行测试
|
|
|
+ return_code = run_tests(
|
|
|
+ test_marker=args.marker,
|
|
|
+ environment=args.env,
|
|
|
+ report_type=args.report
|
|
|
+ )
|
|
|
+
|
|
|
+ # 退出码
|
|
|
+ sys.exit(return_code)
|
|
|
+
|
|
|
+
|
|
|
+if __name__ == '__main__':
|
|
|
+ main()
|