自定义pytest junitxml失败报告

时间:2015-04-08 21:54:22

标签: python logging pytest

我试图反省测试失败并将其他数据包含在junit xml测试报告中。具体来说,这是对外部产品的一系列功能测试,我想将产品的日志包含在故障报告中。

使用找到here的方法,我可以在执行multicall之前将日志打印到stdout,最终会在jenkin的失败报告中显示。但我确信有更好的方法来实现这一目标。

我尝试使用pytest_runtest_logreport挂钩将日志附加到'sections'属性中,该属性已包含'capture stdout'和'capture stderr'流。但是新添加的部分没有进入xml文件。我也尝试将上述技术直接导入到pytest_runtest_makereport钩子中,结果相似。

pytest 2.7的发行说明指出,使用多线程支持将被删除2.8并且@ pytest.mark.hookwrapper是新的方法,但是我似乎无法完成这项工作 - “ yield“返回None而不是CallOutcome对象(在makereport钩子中尝试它)。即使它返回了某些内容,我也不确定是否可以在xml报告中添加内容。

我是否缺少任何可以让我以灵活方式执行此操作的功能? (灵活的我的意思是:没有绑定到stdout或记录像capture-logs插件这样的调用)

3 个答案:

答案 0 :(得分:6)

编辑:由于我需要访问测试项目的funcargs(和测试结果)以进行报告,因此我能够将逻辑移至pytest_runtest_makereport(item, __multicall__)挂钩。诀窍是执行multiicall,它返回报告对象:

@pytest.mark.tryfirst
def pytest_runtest_makereport(item, call, __multicall__):
    report = __multicall__.execute()
    # then I was able to manipulate report and get the same results as below

Bruno的回答给了我更彻底地分析这个功能所需的动力:)

所以这是它的工作原理:

def pytest_runtest_logreport(report):
    if report.failed:
        report.longrepr.sections.append(("Header", "Message", "-"))
        report.sections.append(("Captured stdout", "This is added to stdout"))
        report.sections.append(("Captured stderr", "This is added to stderr"))
        report.sections.append(("Custom Section", "This can only be seen in the console - the xml won't have it."))

longrepr属性仅在出现故障时可用。它需要一个3元组,最后一个值是用于装饰装饰/环绕标题的字符。它将出现在报告的“失败”部分:

----------------------------------- Header ------------------------------------
Message

自定义栏目会创建其他结果部分,以打印到 控制台 。但他们不会成功到junitxml:

------------------------------- Custom Section --------------------------------
This can only be seen in the console - the xml won't have it.

junitxml报告只有2个部分:out和err。要向其添加自定义文本,您必须创建名为“Captured std”的部分,并且只有那些将使其成为xml文件。任何其他名称都将生成一个只能在控制台中看到的自定义部分。

这是使用上面代码生成的junitxml,为了这篇文章的一些重新格式化:

<?xml version="1.0" encoding="utf-8" ?> 
<testsuite errors="0" failures="1" name="pytest" skips="0" tests="1" time="0.646">
  <testcase classname="test_reporting" name="test_fail" time="0.000999927520752">
    <failure message="test failure">
      @ut def test_fail(): > assert 0, "It failed"
      E AssertionError: It failed 
      E assert 0 test_reporting.py:346: AssertionError
      ----------------------------------- Header ------------------------------------
      Message
    </failure> 
    <system-out>This is added to stdout</system-out> 
    <system-err>This is added to stderr</system-err> 
  </testcase>
</testsuite>

答案 1 :(得分:3)

要向测试报告(XML,控制台或其他)添加信息,请查看reporting hooks,更具体地说,请pytest_runtest_logreport

答案 2 :(得分:0)

pytest_runtest_makereport(item, call)@pytest.hookimpl(hookwrapper=True)结合使用可以在报表用于创建xml之前对其进行访问。

@pytest.hookimpl(hookwrapper=True)                                                                                                                                                                                                                                                                                         
def pytest_runtest_makereport(item, call):
    result = yield                                                                                                                                                                                                                                                                                         
    if result.get_result().failed:
        report.longrepr.addsection("Header","message")

使用pytest-3.9.3

尽管the documentation对于hookwrapper确实建议谨慎

  

如果基础钩子的结果是可变对象,他们可能会修改该结果,但最好避免这种情况。