Files
smart-management-auto-test/joyhub_backend/test_case/run_tests.py
2026-05-18 15:20:48 +08:00

171 lines
6.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
import argparse
import os
import shutil
import subprocess
import sys
current_file_path = os.path.abspath(__file__)
project_root = os.path.abspath(os.path.join(os.path.dirname(current_file_path), '../../'))
if project_root not in sys.path:
sys.path.insert(0, project_root)
TEST_CASE_DIR = 'joyhub_backend/test_case/TestCase'
case_dir = os.path.join(project_root, TEST_CASE_DIR)
ALLURE_RESULTS_DIR = os.path.join(project_root, 'joyhub_backend', 'test_case', 'reports', 'allure-results')
ALLURE_REPORT_DIR = os.path.join(project_root, 'joyhub_backend', 'test_case', 'reports', 'allure-report')
def ensure_dirs():
os.makedirs(ALLURE_RESULTS_DIR, exist_ok=True)
os.makedirs(ALLURE_REPORT_DIR, exist_ok=True)
def clean_allure_results():
if os.path.exists(ALLURE_RESULTS_DIR):
shutil.rmtree(ALLURE_RESULTS_DIR)
os.makedirs(ALLURE_RESULTS_DIR, exist_ok=True)
def find_test_files(directory):
test_files = []
for root, dirs, files in os.walk(directory):
for file in files:
if file.endswith('.py') and not file.startswith('__') and file != 'conftest.py':
test_files.append(os.path.join(root, file))
return test_files
def run_pytest(args_list):
env = os.environ.copy()
env['PYTHONPATH'] = project_root + (os.pathsep + env['PYTHONPATH'] if 'PYTHONPATH' in env else '')
cmd = ['python', '-m', 'pytest'] + args_list
print("开始执行pytest...")
print("执行命令: {}".format(' '.join('"{}"'.format(item) if ' ' in item else item for item in cmd)), flush=True)
result = subprocess.run(cmd, cwd=project_root, env=env)
print("pytest执行结束退出码: {}".format(result.returncode), flush=True)
return result.returncode
def run_tests(target=None, test_type='all'):
base_args = ['-v', '--tb=short', '--alluredir={}'.format(ALLURE_RESULTS_DIR)]
if test_type == 'all':
print("运行所有测试用例...")
test_files = find_test_files(case_dir)
if not test_files:
print("错误: 未找到测试文件")
return 1
args = test_files + base_args
elif test_type == 'dir':
full_path = os.path.join(case_dir, target.replace('/', os.sep).replace('\\', os.sep))
if not os.path.exists(full_path):
print("错误: 目录不存在: {}".format(full_path))
return 1
print("按目录运行: {}".format(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.replace('/', os.sep).replace('\\', os.sep))
if not os.path.exists(full_path):
print("错误: 文件不存在: {}".format(full_path))
return 1
print("按文件运行: {}".format(target))
args = [full_path] + base_args
elif test_type == 'keyword':
print("按关键字运行: {}".format(target))
test_files = find_test_files(case_dir)
args = test_files + ['-k={}'.format(target)] + base_args
elif test_type == 'marker':
print("按pytest标记运行: {}".format(target))
test_files = find_test_files(case_dir)
args = test_files + ['-m={}'.format(target)] + base_args
elif test_type == 'feature':
print("按Allure feature运行: {}".format(target))
test_files = find_test_files(case_dir)
args = test_files + ['--allure-features={}'.format(target)] + base_args
elif test_type == 'story':
print("按Allure story运行: {}".format(target))
test_files = find_test_files(case_dir)
args = test_files + ['--allure-stories={}'.format(target)] + base_args
else:
print("错误: 未知的测试类型: {}".format(test_type))
return 1
return run_pytest(args)
def generate_allure_report():
print("开始生成Allure报告...", flush=True)
if os.path.exists(ALLURE_REPORT_DIR):
shutil.rmtree(ALLURE_REPORT_DIR)
cmd = 'allure generate "{}" --output "{}"'.format(ALLURE_RESULTS_DIR, ALLURE_REPORT_DIR)
print("执行命令: {}".format(cmd), flush=True)
try:
subprocess.run(cmd, check=True, shell=True)
print("Allure报告生成成功: {}".format(ALLURE_REPORT_DIR))
print("打开报告命令: allure open \"{}\"".format(ALLURE_REPORT_DIR))
return 0
except (subprocess.CalledProcessError, FileNotFoundError, OSError) as error:
print("生成Allure报告失败: {}".format(error))
print("手动执行: {}".format(cmd))
return 1
def open_allure_report():
cmd = 'allure open "{}"'.format(ALLURE_REPORT_DIR)
try:
subprocess.Popen(cmd, shell=True)
print("Allure报告已打开: {}".format(ALLURE_REPORT_DIR))
return 0
except (FileNotFoundError, OSError) as error:
print("打开Allure报告失败: {}".format(error))
return 1
def main():
parser = argparse.ArgumentParser(description='JoyHub Backend 接口自动化测试执行工具')
run_group = parser.add_mutually_exclusive_group(required=False)
run_group.add_argument('--feature', type=str, help='按Allure feature运行')
run_group.add_argument('--story', type=str, help='按Allure story运行')
run_group.add_argument('--dir', 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('--marker', type=str, help='按pytest标记运行')
parser.add_argument('--report', action='store_true', help='生成Allure报告')
parser.add_argument('--open', action='store_true', help='打开Allure报告')
parser.add_argument('--no-report', action='store_true', help='不生成Allure报告')
args = parser.parse_args()
ensure_dirs()
clean_allure_results()
if args.feature:
exit_code = run_tests(args.feature, 'feature')
elif args.story:
exit_code = run_tests(args.story, 'story')
elif args.dir:
exit_code = run_tests(args.dir, 'dir')
elif args.file:
exit_code = run_tests(args.file, 'file')
elif args.keyword:
exit_code = run_tests(args.keyword, 'keyword')
elif args.marker:
exit_code = run_tests(args.marker, 'marker')
else:
exit_code = run_tests()
if args.report or not args.no_report:
generate_allure_report()
if args.open:
open_allure_report()
print("=" * 80)
print("测试执行完成" if exit_code == 0 else "测试执行失败,退出码: {}".format(exit_code))
print("=" * 80)
sys.exit(exit_code)
if __name__ == '__main__':
main()