import os
import logging
import csv
import datetime
from collections import OrderedDict
import pytest
failed = False
test_results = None
def get_current_test():
"""Just a helper function to extract the current test"""
full_name = os.environ.get('PYTEST_CURRENT_TEST').split(' ')[0]
test_file = full_name.split("::")[0].split('/')[-1].split('.py')[0]
test_name = full_name.split("::")[1]
return full_name, test_file, test_name
def pytest_configure(config):
"""Called when pytest is starting and before running any tests."""
global test_results
test_results = OrderedDict()
test_results['time'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# Initial state is success, only change on failure
test_results['state'] = "Success"
test_results['first_error_message'] = ""
test_results['amount_of_failed_tests'] = 0
def pytest_unconfigure(config):
"""Called when pytest is about to end. Can be used to print the result dict or
to pipe the data into a file"""
create_first_line = False
line_to_be_written = list(test_results.values())
csv_header = list(test_results.keys())
try:
with open(statistics_csv_path) as statistics_csv:
csv_reader = csv.reader(statistics_csv)
header = next(csv_reader)
if header is not None:
for i in range(len(csv_header)):
try:
if header[i] != csv_header[i]:
logger.critical(f"Non matching header column in the csv file: {header[i]} != {csv_header[i]}!!!!")
raise Exception("Probably the csv format of your tests have changed.. please fix!")
except IndexError:
raise Exception("Probably the csv format of your tests have changed.. please fix!")
else:
create_first_line = True
except FileNotFoundError:
create_first_line = True
with open(statistics_csv_path, 'a+', newline='') as statistics_csv:
csv_writer = csv.writer(statistics_csv)
if create_first_line:
csv_writer.writerow(csv_header)
csv_writer.writerow(line_to_be_written)
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
"""The actual wrapper that gets called before and after every test"""
global test_results
outcome = yield
rep = outcome.get_result()
if rep.when == "call":
full_name, test_file, test_name = get_current_test()
test_name_msg = f"{test_name}_msg"
if rep.failed:
test_results['state'] = "Failure"
test_results['amount_of_failed_tests'] += 1
test_results[test_name] = f"Failure"
test_results[test_name_msg] = f"{call.excinfo.typename} - {call.excinfo.value}"
if test_results['first_error_message'] == "":
test_results['first_error_message'] = test_results[test_name_msg]
else:
test_results[test_name] = "Success"
test_results[test_name_msg] = f""
2条答案
按热度按时间sh7euo9m1#
这是一个很长但完整的解决方案(仅Python 3!),它完全按照我上面描述的那样做。它使用pyest中的
conftest.py
。它包括错误处理,用于测试与以前运行的测试不同的情况,在这种情况下,csv文件将被破坏(不同的头)。如果csv文件的头不存在,它将自动生成。此脚本将每次pytest运行的结果附加到csv文件中。此操作在所有测试运行后完成。第一个错误消息记录在
test_results['first_error_message']
中。请在运行之前阅读代码。记住覆盖
statistics_csv_path
,它是存储测试结果的csv文件。km0tfn4u2#
下面是matt3o的回答:https://stackoverflow.com/a/61526655/5351910并做了一些修改和解决了一些问题我创建了一个报告,只写错误: