pytest:如何使用测试类实例变量作为夹具参数

我正在尝试重用一些单元测试功能。唯一可变的部分实际上是测试数据集。因此,我将测试逻辑封装在一个类中,并在创建对象时注入实际的测试数据。

不幸的是,这似乎不适用于@pytest.fixture装饰器。

一些最小的代码来重现。这是我的测试类的通用定义define_test.py

#!/usr/bin/env python3

import pytest

class TestDemo:
    def __init__(self, _data: list):
        self.__testData = _data

    @pytest.fixture(scope='module', params=self.__testData)
    def fixture(self, request):
        return request.param

    def test(self, fixture):
        foo = fixture
        assert foo is not None

预期用途将是这样的 use_test.py

#!/usr/bin/env python3

import define_test

data1 = [1, 2, 3, 4]
test1 = define_test.TestDemo(data1)
data2 = [4, 3, 2, 1]
test2 = define_test.TestDemo(data2)

尝试运行此代码会产生

define_test.py:9: in TestDemo
    ???
E   NameError: name 'self' is not defined

我很确定问题在于,不能简单地将通常的 OO 机制应用于pytest装饰器。看起来要么装饰器在此类的实例存在之前就被评估,要么它根本无法处理实例。

那么,使用可变数据实现可重用测试目标的正确方法是什么?

厘米

您可以通过动态参数化来表达这一点,您可以通过钩子访问 pytest_generate_tests

文档中有一些示例

通过这种方式,您可以在收集时拦截测试并注入您自己的参数化设置。每个测试都会调用钩子,并将metafunc对象作为公开parameterize方法的参数

metafunc 文档在这里

在我看来,您无法访问实例数据,因为此代码是在收集时发生的,在您的对象初始化之前。但是您可以通过 访问类对象metafunc.cls,所以也许您可以在超类中使用您的方法,然后将其子类化以将特定数据案例添加为类属性

这是我正在考虑的事情的一些示例代码

一种) pytestfoo.py

#!/usr/bin/env python3

import pytest


class BaseTest:

    def test(self, testparams):
        print("\n", testparams, "\n")
        assert testparams is not None

class TestCaseA(BaseTest):
    testparams = [[1,2,3,4]]

class TestCaseB(BaseTest):
    testparams = [[4,3,2,1]]

b) 相应的 conftest.py

def pytest_generate_tests(metafunc):
    metafunc.parametrize("testparams", metafunc.cls.testparams)

并使用这些测试运行 pytest


pytest -sv pytestfoo.py
========================================================== test session starts ==========================================================
platform linux -- Python 3.7.6, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- /home/cms/.pyenv/versions/3.7.6/envs/tmp/bin/python3.7
cachedir: .pytest_cache
rootdir: /home/cms/tmp
collected 2 items                                                                                                                       

pytestfoo.py::TestCaseA::test[testparams0] 
 [1, 2, 3, 4] 

PASSED
pytestfoo.py::TestCaseB::test[testparams0] 
 [4, 3, 2, 1] 

PASSED

=========================================================== 2 passed in 0.01s ===========================================================

希望这里对您自己的实验有一些启发。pytest 文档展示了如何使用命令行中的数据进行参数化,这可能比上面的方法更实用,但我试图按照您的指导使用代码定义数据。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何测试pytest夹具本身?

通过自我而不是方法参数的类的Pytest夹具

如何使用夹具在pytest中使异步测试超时?

pytest的夹具参数与monkeypatch

如何使用pytest将夹具中的对象共享给所有测试?

pytest->如何在类下的测试方法中使用夹具返回值

通过夹具到pytest中的测试类

pytest:夹具作为函数参数

如何在每种测试方法(包含在同一测试夹具中)之前每次初始化实例变量(在nunit的测试夹具中声明)?

如何通过pytest夹具进行测试

XUnit是否在测试类之间共享夹具实例?

pytest参数化使用夹具的测试

使用夹具vs传递方法作为参数

pytest:带有夹具的基于参数的类的测试(pytest-django)

如何根据pytest中的夹具参数来参数化测试?

使用通用测试功能中的pytest夹具

如何对测试功能的每个参数执行pytest夹具?

使用gem对象作为实例变量的类的RSpec测试

如何使用类作为变量创建类实例?

Pytest:如何测试从环境变量设置的类变量?

如何实例化作为类实例的类变量?

pytest 每次迭代的新测试| for 循环 | 参数化夹具

为什么我只能通过在测试脚本中使用夹具(来自 pytest)来获取函数作为返回值?

如何将变量从 pytest 夹具转移到实际测试?

Pytest:使用参数创建增量夹具值

如何使用pytest在python中测试没有参数或返回的类的方法

Pytest - 作为参数传递的模拟类实例

使用带有标记参数的 pytest 夹具

如何访问夹具的值作为参数化测试的输入