首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用pytest.hookimpl将pytest函数的返回值写入文件

问用pytest.hookimpl将pytest函数的返回值写入文件
EN

Stack Overflow用户
提问于 2019-07-26 09:23:39
回答 2查看 5.8K关注 0票数 5

我正在寻找一种访问测试函数返回值的方法,以便将该值包含在测试报告文件中(类似于http://doc.pytest.org/en/latest/example/simple.html#post-process-test-reports-failures)。

我想使用的代码示例:

代码语言:javascript
复制
# modified example code from http://doc.pytest.org/en/latest/example/simple.html#post-process-test-reports-failures

import pytest
import os.path

@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
    # execute all other hooks to obtain the report object
    outcome = yield
    rep = outcome.get_result()

    if rep.when == "call" and rep.passed:
        mode = "a" if os.path.exists("return_values") else "w"
        with open("return_values.txt", mode) as f:
            # THE FOLLOWING LINE IS THE ONE I CANNOT FIGURE OUT
            # HOW DO I ACCESS THE TEST FUNCTION RETURN VALUE?
            return_value = item.return_value
            f.write(rep.nodeid + ' returned ' + str(return_value) + "\n")

我期望返回值被写入文件"return_values.txt“。相反,我得到了一个AttributeError。

背景(如果您可以推荐完全不同的方法):

我有一个Python库,用于分析给定问题的数据。我有一个标准的测试数据集,我经常运行我的分析,以产生关于分析算法质量的各种“基准”度量。例如,这样的度量之一是由分析代码产生的标准化混淆矩阵的跟踪(我希望尽可能接近1)。另一个度量是CPU产生分析结果的时间。

我正在寻找一种很好的方法将这些基准测试结果包含到CI框架中(目前是Jenkins),这样就可以很容易地看到commit是提高还是降低了分析性能。由于我已经在CI序列中运行pytest,并且我希望将pytest的各种特性用于我的基准测试(固定、标记、跳过、清理),所以我考虑在pytest中添加一个后处理挂钩(请参阅http://doc.pytest.org/en/latest/example/simple.html#post-process-test-reports-failures),它收集测试函数运行时并返回值,并将它们(或者仅是那些标记为基准的)报告到一个文件中,该文件将由我的CI框架收集并存档为测试工件。

我对解决这个问题的其他方法持开放态度,但是我的google搜索结论是pytest是最接近于提供我所需要的东西的框架。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-26 10:07:54

pytest忽略测试函数的返回值,如在代码中所示

代码语言:javascript
复制
@hookimpl(trylast=True)
def pytest_pyfunc_call(pyfuncitem):
    testfunction = pyfuncitem.obj
    ...
    testfunction(**testargs)
    return True

但是,您可以在测试函数中存储所需的任何内容;为此,我通常使用config对象。示例:在conftest.py中放置以下代码片段

代码语言:javascript
复制
import pathlib
import pytest


def pytest_configure(config):
    # create the dict to store custom data
    config._test_results = dict()


@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
    # execute all other hooks to obtain the report object
    outcome = yield
    rep = outcome.get_result()

    if rep.when == "call" and rep.passed:
        # get the custom data
        return_value = item.config._test_results.get(item.nodeid, None)
        # write to file
        report = pathlib.Path('return_values.txt')
        with report.open('a') as f:
            f.write(rep.nodeid + ' returned ' + str(return_value) + "\n")

现在将数据存储在测试中:

代码语言:javascript
复制
def test_fizz(request):
    request.config._test_results[request.node.nodeid] = 'mydata'
票数 6
EN

Stack Overflow用户

发布于 2019-12-07 19:42:43

分享同样的问题,下面是我想出的另一个解决方案:

在测试中使用夹具record_property:

代码语言:javascript
复制
def test_mytest(record_property):
    record_property("key", 42)

然后在conftest.py中我们可以使用pytest_runtest_teardown 钩子

代码语言:javascript
复制
#conftest.py
def pytest_runtest_teardown(item, nextitem):
    results = dict(item.user_properties)
    if not results:
        return
    with open(f'{item.name}_return_values.txt','a') as f:
        for key, value in results.items():
            f.write(f'{key} = {value}\n')

然后是test_mytest_return_values.txt的含量

代码语言:javascript
复制
key = 42

两个重要的注意事项:

  1. 即使测试失败,也将执行此代码。我想不出有什么办法能得到测试结果。
  2. 这可以与希尔夫的答案结合起来,使用results = dict(item.user_properties)获取在测试中添加的键和值,而不是在配置中添加一个dict,然后在测试中访问它。
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57216970

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档