python - 在 pytest 产量 fixture 中使用 request.function 时出现 AttributeError

标签 python pytest fixtures

我有几个需要几乎相同设置的 pytest 测试用例,所以我想让它们重用一个固定装置来保持干燥。该设置涉及在外部票证跟踪系统中创建新票证,然后测试用例根据数据与票证进行交互,最后固定装置通过关闭票证进行清理。这里的挑战是每个测试用例需要在票证中准备略有不同的数据。

每个测试用例都有不同的调用和不同的断言,因此我无法将它们全部组合到具有单个测试 fixture 的单个参数化测试用例中。对 fixture 本身进行参数化将导致每个测试用例都运行 fixture 数据的每个排列,这最终会导致许多不相关的测试失败。

我想要做的是在测试用例中设置一个变量,然后让 fixture 在创建票证时使用该变量来设置测试数据。我尝试使用 pytest fixture docs 中指定的 request.function但我不断得到:

=================================== ERRORS ===================================
    ____________________ ERROR at setup of TestMCVE.test_stuff ___________________

request = <SubRequest 'ticket' for <Function 'test_stuff'>>

    @pytest.yield_fixture
    def ticket(request):
>       ticket_summary = getattr(request.function, "summary")
E       AttributeError: 'function' object has no attribute 'summary'

tests\test_mcve.py:11: AttributeError

我的代码是:

import pytest


def ticket_system_api(summary):
    # stub for MCVE purposes
    return summary


@pytest.yield_fixture
def ticket(request):
    ticket_summary = getattr(request.function, "summary")
    new_ticket = ticket_system_api(summary=ticket_summary)
    yield new_ticket


class TestMCVE:
    def test_stuff(self, ticket):
        summary = 'xyz'
        # do real things here, except MCVE
        assert 'xyz' == ticket

我尝试使用 request.node 而不是 request.function 以及 binding the summary variable per this answer ,将 summary = 'xyz' 更改为 test_stuff.summary = 'xyz' 但这些仍然失败,并出现相同的 AttributeError。

如何将功能级数据传递给 fixture ?

最佳答案

您可以使用 indirect parametrization 来完成此操作。 API(和文档)可能更友好,但您想要的功能已经有了。

您的示例非常接近,需要进行一些细微的调整。看看:

import pytest


def ticket_system_api(summary):
    # stub for MCVE purposes
    return summary


@pytest.fixture
def ticket(request):
    # NOTE: This will raise `AttributeError` if the fixture
    # doesn't receive a parameter.
    ticket_summary = request.param
    new_ticket = ticket_system_api(summary=ticket_summary)
    return new_ticket


class TestMCVE:
    @pytest.mark.parametrize('ticket', ('abc',), indirect=True)
    def test_abc(self, ticket):
        # do real things here, except MCVE
        assert ticket == 'abc'

    @pytest.mark.parametrize('ticket', ('xyz',), indirect=True)
    def test_xyz(self, ticket):
        # do real things here, except MCVE
        assert ticket == 'xyz'

关于python - 在 pytest 产量 fixture 中使用 request.function 时出现 AttributeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38488571/

相关文章:

python - VS Code/Python/使用调试器调试 pytest 测试

python-3.6 - QApplication 实例/qtbot fixture 导致 travis-ci 中止和核心转储

doctrine - Symfony2 将数据库导出到 Doctrine 装置

ruby-on-rails - 你如何使用带有 attr_encrypted 的装置

scala - 如何将共享测试与需要清理的装置结合起来?

python - 如何在其他代码行同时执行时播放声音?

python - 如何在 python 中使用 lxml 去除 xml 标签中的所有子标签,但保留文本合并到 parens?

python - 从 peer 包中导入 conftest.py

python - 删除差异但保持 python 列表中的顺序和重复项

python - 意外的性能下降