在发生故障时控制 pytests 夹具报告

问题描述 投票:0回答:2

我有很多使用随机生成的数据作为输入的测试。为了确保失败是可重复的,我将它们组织如下:

import random
import pytest   

@pytest.fixture
def seed():
    return random.getrandbits(32)


def test_foo(seed):
    # seed the random number generators, and generate random data
    # test foo

def test_bar(seed):
    # seed the random number generators, and generate random data
    # test bar

def test_baz(seed):
    # seed the random number generators, and generate random data
    # test baz

这样,如果发生故障,pytest 会报告

seed
的值,我可以临时更改
seed()
固定装置以返回该特定值,修复故障,然后将其恢复。 (可能有更优雅的方法来做到这一点。)

上述结构的一个问题是,每次测试中都会重复大量代码来生成随机数据。

因此,我决定将测试模块重构为:

import random
import pytest   

@pytest.fixture
def seed():
    return random.getrandbits(32)

@pytest.fixture
def stimulus(seed):
    # seed the random number generators and generate random data
    return data 


def test_foo(stimulus):
    # test foo

def test_bar(stimulus):
    # test bar

def test_baz(stimulus):
    # test baz

现在测试仍然是可重复的,因为如果

seed()
夹具返回(或重写返回)相同的值,我们会得到相同的测试结果。但是,如果失败,pytest 会打印出
stimulus
的值,该值通常太长而无法显示在屏幕上。 (另外,更改
stimulus()
以返回完全相同的数据会更加困难。)

有没有办法告诉 pytest“如果失败,打印出最后一个固定装置的值,即

seed
而不是第一个固定装置
stimulus
”?

python-3.x pytest
2个回答
0
投票

您可以做的一件事(如果您也可以看到

stimulus
的输出)是让
stimulus
夹具返回
(seed, data)
(并相应地调整您的测试函数)并在 pytest 命令中包含开关
--showlocals
。这样,您将看到夹具的值,只是现在它也显示了
seed
的值..


0
投票

测试后使用产量夹具清理:

import base64, random, secrets, pytest

@pytest.fixture()
def seed(request):
    seed = secrets.randbits(32)
    yield seed
    if request.session.testsfailed:
        request.session.warn(UserWarning(f"{request.node.name} seed was {seed}"))

@pytest.fixture()
def stimulus(seed: int):
    return random.Random(seed).randbytes(12)

def test_pass(stimulus):
    assert len(base64.b64encode(stimulus)) == 16

def test_fail(stimulus):
    assert len(base64.b64encode(stimulus)) == 12

上面的示例使用警告将种子提供给开发人员。输出看起来像这样:

tests/so.py::test_fail
  overflow:0: UserWarning: test_fail seed was 3753932574

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
© www.soinside.com 2019 - 2024. All rights reserved.