有没有办法在csv文件中收集多次运行的pytest结果?

rsaldnfx  于 2023-02-01  发布在  其他
关注(0)|答案(2)|浏览(117)

我有一个系统,有时会有错误,而引导,这是我用pytest测试.我想收集的结果在csv文件,这样我就可以分析所有运行的结果之后很容易.如果引导失败,我想得到的结果,第一个测试用例失败.

sh7euo9m

sh7euo9m1#

这是一个很长但完整的解决方案(仅Python 3!),它完全按照我上面描述的那样做。它使用pyest中的conftest.py。它包括错误处理,用于测试与以前运行的测试不同的情况,在这种情况下,csv文件将被破坏(不同的头)。如果csv文件的头不存在,它将自动生成。
此脚本将每次pytest运行的结果附加到csv文件中。此操作在所有测试运行后完成。第一个错误消息记录在test_results['first_error_message']中。
请在运行之前阅读代码。记住覆盖statistics_csv_path,它是存储测试结果的csv文件。

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""
km0tfn4u

km0tfn4u2#

下面是matt3o的回答:https://stackoverflow.com/a/61526655/5351910并做了一些修改和解决了一些问题我创建了一个报告,只写错误:

import os
import csv
import pytest

statistics_csv_path = 'test_result.csv'

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

@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
    """The actual wrapper that gets called before and after every test"""
    single_result = []
    outcome = yield
    rep = outcome.get_result()
    if rep.when == "call":
        full_name, test_file, test_name = get_current_test()
        single_result.append(test_file)
        single_result.append(test_name)

        if rep.outcome == "failed":
            single_result.append("FAILED")
            single_result.append(f"{call.excinfo.typename} - {call.excinfo.value}")

            csv_header = ['test_file', 'test_name', 'state', 'message']
            create_first_line = False
            try:
                with open(statistics_csv_path) as statistics_csv:
                    csv_reader = csv.reader(statistics_csv)
                    header = next(csv_reader)
                    if header is None:
                        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(single_result)

相关问题