修改路径地址
This commit is contained in:
@@ -3,11 +3,10 @@
|
|||||||
统一测试执行文件
|
统一测试执行文件
|
||||||
支持批量运行所有用例、按标签运行、按目录运行等
|
支持批量运行所有用例、按标签运行、按目录运行等
|
||||||
"""
|
"""
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import subprocess
|
|
||||||
import argparse
|
import argparse
|
||||||
from pathlib import Path
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
# 添加项目根目录到 Python 路径
|
# 添加项目根目录到 Python 路径
|
||||||
current_file_path = os.path.abspath(__file__)
|
current_file_path = os.path.abspath(__file__)
|
||||||
@@ -15,8 +14,10 @@ project_root = os.path.abspath(os.path.join(os.path.dirname(current_file_path),
|
|||||||
if project_root not in sys.path:
|
if project_root not in sys.path:
|
||||||
sys.path.insert(0, project_root)
|
sys.path.insert(0, project_root)
|
||||||
|
|
||||||
|
print(project_root)
|
||||||
# 测试目录
|
# 测试目录
|
||||||
TEST_CASE_DIR = 'zhyy/test_case/TestCase'
|
TEST_CASE_DIR = 'zhyy/test_case/TestCase'
|
||||||
|
case_dir = os.path.join(project_root,TEST_CASE_DIR)
|
||||||
# 报告目录
|
# 报告目录
|
||||||
REPORT_DIR = os.path.join(os.path.dirname(current_file_path), 'reports')
|
REPORT_DIR = os.path.join(os.path.dirname(current_file_path), 'reports')
|
||||||
ALLURE_RESULTS_DIR = os.path.join(REPORT_DIR, 'allure-results')
|
ALLURE_RESULTS_DIR = os.path.join(REPORT_DIR, 'allure-results')
|
||||||
@@ -31,43 +32,23 @@ def ensure_dirs():
|
|||||||
|
|
||||||
def run_pytest(args_list):
|
def run_pytest(args_list):
|
||||||
"""执行pytest命令"""
|
"""执行pytest命令"""
|
||||||
# 基础pytest命令
|
# 设置PYTHONPATH环境变量
|
||||||
# 设置PYTHONPATH环境变量,确保能导入zhyy模块
|
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
if 'PYTHONPATH' in env:
|
env['PYTHONPATH'] = project_root + (os.pathsep + env['PYTHONPATH'] if 'PYTHONPATH' in env else '')
|
||||||
env['PYTHONPATH'] = project_root + os.pathsep + env['PYTHONPATH']
|
|
||||||
else:
|
|
||||||
env['PYTHONPATH'] = project_root
|
|
||||||
|
|
||||||
# 检测是否在Jenkins环境中
|
# 检测Jenkins环境
|
||||||
is_jenkins = 'JENKINS_URL' in env or 'BUILD_NUMBER' in env
|
is_jenkins = 'JENKINS_URL' in env or 'BUILD_NUMBER' in env
|
||||||
if is_jenkins:
|
if is_jenkins and 'WORKSPACE' in env:
|
||||||
print("检测到Jenkins环境,使用Jenkins配置...")
|
# Jenkins环境下使用绝对路径
|
||||||
# 在Jenkins中,报告路径使用绝对路径
|
global ALLURE_RESULTS_DIR, ALLURE_REPORT_DIR
|
||||||
if 'WORKSPACE' in env:
|
ALLURE_RESULTS_DIR = os.path.join(env['WORKSPACE'], 'zhyy', 'test_case', 'reports', 'allure-results')
|
||||||
workspace = env['WORKSPACE']
|
ALLURE_REPORT_DIR = os.path.join(env['WORKSPACE'], 'zhyy', 'test_case', 'reports', 'allure-report')
|
||||||
# 确保使用Jenkins工作空间的报告目录
|
ensure_dirs()
|
||||||
global ALLURE_RESULTS_DIR, ALLURE_REPORT_DIR
|
|
||||||
ALLURE_RESULTS_DIR = os.path.join(workspace, 'zhyy', 'test_case', 'reports', 'allure-results')
|
|
||||||
ALLURE_REPORT_DIR = os.path.join(workspace, 'zhyy', 'test_case', 'reports', 'allure-report')
|
|
||||||
ensure_dirs()
|
|
||||||
|
|
||||||
cmd = ['python', '-m', 'pytest'] + args_list
|
cmd = ['python', '-m', 'pytest'] + args_list
|
||||||
|
print(f"执行命令: {' '.join(cmd)}")
|
||||||
|
|
||||||
print("=" * 80)
|
# 执行命令
|
||||||
print("执行命令: {}".format(' '.join(cmd)))
|
|
||||||
print("命令列表: {}".format(cmd))
|
|
||||||
print("测试目录: {}".format(TEST_CASE_DIR))
|
|
||||||
print("测试目录是否存在: {}".format(os.path.exists(TEST_CASE_DIR)))
|
|
||||||
if is_jenkins:
|
|
||||||
print("Jenkins工作空间: {}".format(env.get('WORKSPACE', 'N/A')))
|
|
||||||
print("构建编号: {}".format(env.get('BUILD_NUMBER', 'N/A')))
|
|
||||||
print("PYTHONPATH: {}".format(env.get('PYTHONPATH')))
|
|
||||||
print("Allure结果目录: {}".format(ALLURE_RESULTS_DIR))
|
|
||||||
print("当前工作目录: {}".format(os.getcwd()))
|
|
||||||
print("=" * 80)
|
|
||||||
|
|
||||||
# 使用 shell=True 来执行命令,确保能正确处理路径和参数
|
|
||||||
result = subprocess.run(' '.join(cmd), shell=True, cwd=project_root, env=env)
|
result = subprocess.run(' '.join(cmd), shell=True, cwd=project_root, env=env)
|
||||||
return result.returncode
|
return result.returncode
|
||||||
|
|
||||||
@@ -77,162 +58,100 @@ def find_test_files(directory):
|
|||||||
test_files = []
|
test_files = []
|
||||||
for root, dirs, files in os.walk(directory):
|
for root, dirs, files in os.walk(directory):
|
||||||
for file in files:
|
for file in files:
|
||||||
if file.endswith('.py'):
|
if file.endswith('.py') and not file.startswith('__'):
|
||||||
# 检查文件中是否包含测试函数
|
test_files.append(os.path.join(root, file))
|
||||||
file_path = os.path.join(root, file)
|
|
||||||
try:
|
|
||||||
with open(file_path, 'r', encoding='utf-8') as f:
|
|
||||||
content = f.read()
|
|
||||||
if 'def test_' in content or 'class Test' in content:
|
|
||||||
test_files.append(file_path)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
return test_files
|
return test_files
|
||||||
|
|
||||||
|
|
||||||
def run_all_tests():
|
def run_tests(target, test_type='all', **kwargs):
|
||||||
"""运行所有测试用例"""
|
"""运行测试"""
|
||||||
print("运行所有测试用例...")
|
base_args = ['-v', '--tb=short', f'--alluredir={ALLURE_RESULTS_DIR}']
|
||||||
# 递归查找所有测试文件
|
|
||||||
test_files = find_test_files(TEST_CASE_DIR)
|
if test_type == 'all':
|
||||||
if not test_files:
|
print("运行所有测试用例...")
|
||||||
print("未找到测试文件")
|
test_files = find_test_files(case_dir)
|
||||||
|
if not test_files:
|
||||||
|
print("错误: 未找到测试文件")
|
||||||
|
return 1
|
||||||
|
args = test_files + base_args
|
||||||
|
elif test_type == 'feature':
|
||||||
|
print(f"按feature标签运行: {target}")
|
||||||
|
test_files = find_test_files(case_dir)
|
||||||
|
if not test_files:
|
||||||
|
print("错误: 未找到测试文件")
|
||||||
|
return 1
|
||||||
|
args = test_files + [f'--allure-features={target}'] + base_args
|
||||||
|
elif test_type == 'story':
|
||||||
|
print(f"按story标签运行: {target}")
|
||||||
|
test_files = find_test_files(case_dir)
|
||||||
|
if not test_files:
|
||||||
|
print("错误: 未找到测试文件")
|
||||||
|
return 1
|
||||||
|
args = test_files + [f'--allure-stories={target}'] + base_args
|
||||||
|
elif test_type == 'marker':
|
||||||
|
print(f"按pytest标记运行: {target}")
|
||||||
|
test_files = find_test_files(case_dir)
|
||||||
|
if not test_files:
|
||||||
|
print("错误: 未找到测试文件")
|
||||||
|
return 1
|
||||||
|
args = test_files + [f'-m={target}'] + base_args
|
||||||
|
elif test_type == 'dir':
|
||||||
|
full_path = os.path.join(case_dir, target)
|
||||||
|
if not os.path.exists(full_path):
|
||||||
|
print(f"错误: 目录不存在: {full_path}")
|
||||||
|
return 1
|
||||||
|
print(f"按目录运行: {target}")
|
||||||
|
test_files = find_test_files(full_path)
|
||||||
|
if not test_files:
|
||||||
|
print("错误: 未找到测试文件")
|
||||||
|
return 1
|
||||||
|
args = test_files + base_args
|
||||||
|
elif test_type == 'file':
|
||||||
|
full_path = os.path.join(case_dir, target)
|
||||||
|
if not os.path.exists(full_path):
|
||||||
|
print(f"错误: 文件不存在: {full_path}")
|
||||||
|
return 1
|
||||||
|
print(f"按文件运行: {target}")
|
||||||
|
args = [full_path] + base_args
|
||||||
|
elif test_type == 'keyword':
|
||||||
|
print(f"按关键字运行: {target}")
|
||||||
|
test_files = find_test_files(case_dir)
|
||||||
|
if not test_files:
|
||||||
|
print("错误: 未找到测试文件")
|
||||||
|
return 1
|
||||||
|
args = test_files + [f'-k={target}'] + base_args
|
||||||
|
else:
|
||||||
|
print(f"错误: 未知的测试类型: {test_type}")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
print(f"找到 {len(test_files)} 个测试文件:")
|
|
||||||
for file in test_files:
|
|
||||||
print(f" - {file}")
|
|
||||||
|
|
||||||
args = [
|
|
||||||
*test_files,
|
|
||||||
'-v', # 详细输出
|
|
||||||
'--tb=short', # 简短的错误信息
|
|
||||||
f'--alluredir={ALLURE_RESULTS_DIR}', # allure结果目录
|
|
||||||
]
|
|
||||||
return run_pytest(args)
|
|
||||||
|
|
||||||
|
|
||||||
def run_by_feature(feature_name):
|
|
||||||
"""按allure feature标签运行"""
|
|
||||||
print("按feature标签运行: {}".format(feature_name))
|
|
||||||
args = [
|
|
||||||
TEST_CASE_DIR,
|
|
||||||
'-v',
|
|
||||||
'--tb=short',
|
|
||||||
f'--allure-features={feature_name}',
|
|
||||||
f'--alluredir={ALLURE_RESULTS_DIR}',
|
|
||||||
]
|
|
||||||
return run_pytest(args)
|
|
||||||
|
|
||||||
|
|
||||||
def run_by_story(story_name):
|
|
||||||
"""按allure story标签运行"""
|
|
||||||
print("按story标签运行: {}".format(story_name))
|
|
||||||
args = [
|
|
||||||
TEST_CASE_DIR,
|
|
||||||
'-v',
|
|
||||||
'--tb=short',
|
|
||||||
f'--allure-stories={story_name}',
|
|
||||||
f'--alluredir={ALLURE_RESULTS_DIR}',
|
|
||||||
]
|
|
||||||
return run_pytest(args)
|
|
||||||
|
|
||||||
|
|
||||||
def run_by_marker(marker):
|
|
||||||
"""按pytest标记运行"""
|
|
||||||
print("按pytest标记运行: {}".format(marker))
|
|
||||||
args = [
|
|
||||||
TEST_CASE_DIR,
|
|
||||||
'-v',
|
|
||||||
'--tb=short',
|
|
||||||
f'-m={marker}',
|
|
||||||
f'--alluredir={ALLURE_RESULTS_DIR}',
|
|
||||||
]
|
|
||||||
return run_pytest(args)
|
|
||||||
|
|
||||||
|
|
||||||
def run_by_dir(directory):
|
|
||||||
"""按目录运行"""
|
|
||||||
full_path = os.path.join(TEST_CASE_DIR, directory)
|
|
||||||
if not os.path.exists(full_path):
|
|
||||||
print("错误: 目录不存在: {}".format(full_path))
|
|
||||||
return 1
|
|
||||||
|
|
||||||
print("按目录运行: {}".format(directory))
|
|
||||||
args = [
|
|
||||||
full_path,
|
|
||||||
'-v',
|
|
||||||
'--tb=short',
|
|
||||||
f'--alluredir={ALLURE_RESULTS_DIR}',
|
|
||||||
]
|
|
||||||
return run_pytest(args)
|
|
||||||
|
|
||||||
|
|
||||||
def run_by_file(file_path):
|
|
||||||
"""按文件运行"""
|
|
||||||
full_path = os.path.join(TEST_CASE_DIR, file_path)
|
|
||||||
if not os.path.exists(full_path):
|
|
||||||
print("错误: 文件不存在: {}".format(full_path))
|
|
||||||
return 1
|
|
||||||
|
|
||||||
print("按文件运行: {}".format(file_path))
|
|
||||||
args = [
|
|
||||||
full_path,
|
|
||||||
'-v',
|
|
||||||
'--tb=short',
|
|
||||||
f'--alluredir={ALLURE_RESULTS_DIR}',
|
|
||||||
]
|
|
||||||
return run_pytest(args)
|
|
||||||
|
|
||||||
|
|
||||||
def run_by_keyword(keyword):
|
|
||||||
"""按关键字运行(匹配文件名或类名)"""
|
|
||||||
print("按关键字运行: {}".format(keyword))
|
|
||||||
args = [
|
|
||||||
TEST_CASE_DIR,
|
|
||||||
'-v',
|
|
||||||
'--tb=short',
|
|
||||||
f'-k={keyword}',
|
|
||||||
f'--alluredir={ALLURE_RESULTS_DIR}',
|
|
||||||
]
|
|
||||||
return run_pytest(args)
|
return run_pytest(args)
|
||||||
|
|
||||||
|
|
||||||
def generate_allure_report():
|
def generate_allure_report():
|
||||||
"""生成allure报告"""
|
"""生成allure报告"""
|
||||||
print("生成Allure报告...")
|
print("生成Allure报告...")
|
||||||
cmd = [
|
cmd = f'allure generate {ALLURE_RESULTS_DIR} -o {ALLURE_REPORT_DIR} --clean'
|
||||||
'allure',
|
|
||||||
'generate',
|
|
||||||
ALLURE_RESULTS_DIR,
|
|
||||||
'-o',
|
|
||||||
ALLURE_REPORT_DIR,
|
|
||||||
'--clean'
|
|
||||||
]
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 使用shell=True来执行命令,确保使用正确的环境变量
|
subprocess.run(cmd, shell=True, check=True)
|
||||||
result = subprocess.run(' '.join(cmd), shell=True, check=True)
|
print(f"Allure报告生成成功: {ALLURE_REPORT_DIR}")
|
||||||
print("Allure报告生成成功: {}".format(ALLURE_REPORT_DIR))
|
print(f"打开报告命令: allure open {ALLURE_REPORT_DIR}")
|
||||||
print("打开报告命令: allure open {}".format(ALLURE_REPORT_DIR))
|
|
||||||
return 0
|
return 0
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
print("生成Allure报告失败: {}".format(e))
|
print(f"生成Allure报告失败: {e}")
|
||||||
return 1
|
return 1
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print("警告: 未找到allure命令,请先安装allure")
|
print("警告: 未找到allure命令,请先安装allure")
|
||||||
print("安装方法: https://docs.qameta.io/allure/")
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
def open_allure_report():
|
def open_allure_report():
|
||||||
"""打开allure报告"""
|
"""打开allure报告"""
|
||||||
print("打开Allure报告...")
|
print("打开Allure报告...")
|
||||||
cmd = ['allure', 'open', ALLURE_REPORT_DIR]
|
cmd = f'allure open {ALLURE_REPORT_DIR}'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 使用shell=True来执行命令,确保使用正确的环境变量
|
subprocess.Popen(cmd, shell=True)
|
||||||
subprocess.Popen(' '.join(cmd), shell=True)
|
|
||||||
print("Allure报告已在浏览器中打开")
|
print("Allure报告已在浏览器中打开")
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print("警告: 未找到allure命令,请先安装allure")
|
print("警告: 未找到allure命令,请先安装allure")
|
||||||
@@ -241,72 +160,58 @@ def open_allure_report():
|
|||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description='统一测试执行工具',
|
description='统一测试执行工具',
|
||||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
||||||
epilog="""
|
epilog="""
|
||||||
使用示例:
|
使用示例:
|
||||||
# 运行所有测试
|
# 运行所有测试
|
||||||
python run_tests.py --all
|
python run_tests.py
|
||||||
|
|
||||||
# 按feature标签运行
|
# 按feature标签运行
|
||||||
python run_tests.py --feature "深圳采购工作台采购订单页面"
|
python run_tests.py --feature "深圳采购工作台采购订单页面"
|
||||||
|
|
||||||
# 按story标签运行
|
|
||||||
python run_tests.py --story "验证采购工作台采购订单页面列表查询"
|
|
||||||
|
|
||||||
# 按目录运行
|
# 按目录运行
|
||||||
python run_tests.py --dir "接口/SZPurchase"
|
python run_tests.py --dir "接口/SZPurchase"
|
||||||
|
|
||||||
# 按文件运行
|
|
||||||
python run_tests.py --file "接口/SZPurchase/PurchaseOrderManage.py"
|
|
||||||
|
|
||||||
# 按关键字运行
|
|
||||||
python run_tests.py --keyword "purchase"
|
|
||||||
|
|
||||||
# 按pytest标记运行
|
|
||||||
python run_tests.py --marker "smoke"
|
|
||||||
|
|
||||||
# 生成并打开报告
|
# 生成并打开报告
|
||||||
python run_tests.py --all --report --open
|
python run_tests.py --report --open
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
# 运行选项(不强制要求,默认运行所有测试)
|
# 运行选项
|
||||||
run_group = parser.add_mutually_exclusive_group(required=False)
|
run_group = parser.add_mutually_exclusive_group(required=False)
|
||||||
run_group.add_argument('--all', action='store_true', help='运行所有测试用例(默认)')
|
|
||||||
run_group.add_argument('--feature', type=str, help='按allure feature标签运行')
|
run_group.add_argument('--feature', type=str, help='按allure feature标签运行')
|
||||||
run_group.add_argument('--story', type=str, help='按allure story标签运行')
|
run_group.add_argument('--story', type=str, help='按allure story标签运行')
|
||||||
run_group.add_argument('--dir', type=str, help='按目录运行(相对于TestCase目录)')
|
run_group.add_argument('--dir', type=str, help='按目录运行(相对于TestCase目录)')
|
||||||
run_group.add_argument('--file', type=str, help='按文件运行(相对于TestCase目录)')
|
run_group.add_argument('--file', type=str, help='按文件运行(相对于TestCase目录)')
|
||||||
run_group.add_argument('--keyword', type=str, help='按关键字运行(匹配文件名或类名)')
|
run_group.add_argument('--keyword', type=str, help='按关键字运行')
|
||||||
run_group.add_argument('--marker', type=str, help='按pytest标记运行')
|
run_group.add_argument('--marker', type=str, help='按pytest标记运行')
|
||||||
|
|
||||||
# 报告选项
|
# 报告选项
|
||||||
parser.add_argument('--report', action='store_true', help='生成Allure报告')
|
parser.add_argument('--report', action='store_true', help='生成Allure报告')
|
||||||
parser.add_argument('--open', action='store_true', help='打开Allure报告(需要先使用--report)')
|
parser.add_argument('--open', action='store_true', help='打开Allure报告')
|
||||||
parser.add_argument('--no-report', action='store_true', help='不生成Allure报告(默认会生成)')
|
parser.add_argument('--no-report', action='store_true', help='不生成Allure报告')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# 确保目录存在
|
# 确保目录存在
|
||||||
ensure_dirs()
|
ensure_dirs()
|
||||||
|
|
||||||
# 执行测试(如果没有指定选项,默认运行所有测试)
|
# 执行测试
|
||||||
exit_code = 0
|
exit_code = 0
|
||||||
if args.feature:
|
if args.feature:
|
||||||
exit_code = run_by_feature(args.feature)
|
exit_code = run_tests(args.feature, 'feature')
|
||||||
elif args.story:
|
elif args.story:
|
||||||
exit_code = run_by_story(args.story)
|
exit_code = run_tests(args.story, 'story')
|
||||||
elif args.dir:
|
elif args.dir:
|
||||||
exit_code = run_by_dir(args.dir)
|
exit_code = run_tests(args.dir, 'dir')
|
||||||
elif args.file:
|
elif args.file:
|
||||||
exit_code = run_by_file(args.file)
|
exit_code = run_tests(args.file, 'file')
|
||||||
elif args.keyword:
|
elif args.keyword:
|
||||||
exit_code = run_by_keyword(args.keyword)
|
exit_code = run_tests(args.keyword, 'keyword')
|
||||||
elif args.marker:
|
elif args.marker:
|
||||||
exit_code = run_by_marker(args.marker)
|
exit_code = run_tests(args.marker, 'marker')
|
||||||
else:
|
else:
|
||||||
# 默认运行所有测试
|
# 默认运行所有测试
|
||||||
exit_code = run_all_tests()
|
exit_code = run_tests(None, 'all')
|
||||||
|
|
||||||
# 生成报告
|
# 生成报告
|
||||||
if args.report or (not args.no_report and exit_code == 0):
|
if args.report or (not args.no_report and exit_code == 0):
|
||||||
@@ -315,10 +220,7 @@ def main():
|
|||||||
open_allure_report()
|
open_allure_report()
|
||||||
|
|
||||||
print("=" * 80)
|
print("=" * 80)
|
||||||
if exit_code == 0:
|
print("✓ 测试执行完成" if exit_code == 0 else f"✗ 测试执行失败,退出码: {exit_code}")
|
||||||
print("✓ 测试执行完成")
|
|
||||||
else:
|
|
||||||
print("✗ 测试执行失败,退出码: {}".format(exit_code))
|
|
||||||
print("=" * 80)
|
print("=" * 80)
|
||||||
|
|
||||||
sys.exit(exit_code)
|
sys.exit(exit_code)
|
||||||
|
|||||||
Reference in New Issue
Block a user