pytest 之pytest.hookimpl 使用钩子函数pytest_runtest_makereport实现日志收集

pytest_runtest_makereport

对于给定的测试用例(item)和调用步骤(call),返回一个测试报告对象

这个钩子函数会被每个测试用例调用 3 次,分别是:
用例的 setup 执行完毕后,调用 1 次,返回 setup 的执行结果;
用例执行完毕之后,调用 1 次,返回测试用例的执行结果;
用例的 teardown 执行完毕后,调用1 次,返回 teardown 的执行结果;


@pytest.hookimpl(hookwrapper=True, tryfirst=False)
def pytest_runtest_makereport(item, call):
    # 获取钩子方法的调用结果,返回一个result对象
    out = yield
    # 获取调用结果的测试报告,返回一个report对象, report对象的属性包括when(steup, call, teardown三个值)、nodeid(测试用例的名字)、outcome(用例的执行结果,passed,failed)、longreprtext运行错误时的日志、常规日志输出head_line
    report = out.get_result()

根据以上的表现我们可以收集每一个类运行时所产生日志内容输出到文件中
在根目录下创建conftest.py

_file_object = None
_filename = ""

def pytest_exception_interact(node, call, report):
    # 异常日志的收集
    if report.longreprtext:
        write_log("\n" + format_log(report.longreprtext, "ERROR", back_count=2))


@pytest.hookimpl(hookwrapper=True, tryfirst=False)
def pytest_runtest_makereport(item, call):
    # 获取钩子方法的调用结果,返回一个result对象
    out = yield
    # 获取调用结果的测试报告,返回一个report对象, reportd对象的属性包括when(steup, call, teardown三个值)、nodeid(测试用例的名字)、outcome(用例的执行结果,passed,failed)
    report = out.get_result()
    collect_logs(report)


def collect_logs(report):
    global _filename, _file_object
    filename = report.location[0].replace("\\", ".").replace(".py", ".log")
    title = "测试模块:{}".format(report.location[0].replace("\\", ".").replace(".py", ""))
    filename = "./logs/" + filename
    if _filename == "":
        _filename = filename

    if _filename != filename:
        print(_filename, filename)
        _filename = filename
        write_log("", True)
        _file_object = None

    if _file_object is None:
        write_log(title)

    if report.when == "teardown":
        write_log("\n" + report.head_line + "\n")
        write_log(report.caplog)


def write_log(logs, clear=False):
    global _file_object, _filename
    if clear and _file_object:
        _file_object.close()
        return
    if _file_object is None:
        _file_object = open(_filename, 'a', encoding="utf-8")
        _file_object.truncate(0)
    _file_object.writelines(logs)

收集结果 case_log:
image

测试模块:testcase.account.CreateAccountTest
CreateAccountTest.create_account_test[name-age0]
2020-07-14 04:20:09 INFO  CreateAccountTest.create_account_test:12 执行用例: 创建账户:name , 年龄: age.......
CreateAccountTest.create_account_test[name-age1]
2020-07-14 04:20:09 INFO  CreateAccountTest.create_account_test:12 执行用例: 创建账户:name , 年龄: age.......

其中还使用到了钩子pytest_exception_interact, 在每一个运行阶段执行时发生异常时执行;
不使用此钩子也可以实现, pytest_runtest_makereport钩子同样也有异常日志的属性

posted @ 2020-07-14 04:23  silence022  阅读(584)  评论(0)    收藏  举报