pytest夹具的多个副本

时间:2014-02-05 17:09:47

标签: python django testing pytest

假设我有一个如下所示的简单夹具(使用pytest-django,但它也适用于pytest):

@pytest.fixture
def my_thing(request, db):
    thing = MyModel.objects.create()
    request.addfinalizer(lambda: thing.delete())
    return thing

当我的测试需要单个MyModel实例时,这非常有用。但是,如果我需要两个(或三个或四个)呢?我希望每个实例都是不同的,但要以相同的方式设置。

我可以复制/粘贴代码并重命名fixture功能,但这似乎不够优雅。

同样,我尝试过:

@pytest.fixture
def my_thing_1(my_thing):
    return my_thing

@pytest.fixture
def my_thing_2(my_thing):
    return my_thing

但是,其中每个都会返回相同的MyModel实例。

有没有办法用pytest的内置功能做我想做的事情?或者,我可以将我的装置的设置/拆卸移动到辅助函数中,所以我不会复制太多的代码。

或者我是以错误的方式处理这件事?

2 个答案:

答案 0 :(得分:22)

我的方法可能是创建一个可以生成对象的夹具:

@pytest.fixture
def thing(request, db):
    class ThingFactory(object):
        def get(self):
            thing = MyModel.objects.create()
            request.addfinalizer(thing.delete)
            return thing
    return ThingFactory()

def test_thing(thing):
    thing1 = thing.get()
    thing2 = thing.get()

显然你可以让.get()进行争论等。

(PS:另请注意,终结者不需要lambda)

答案 1 :(得分:0)

我很晚才到达这个问题......但是,使用参数化装置并简单地返回你想要复制的装置似乎也有用。

import pytest
import random

@pytest.fixture
def name():
    return random.randint(0, 10)


@pytest.fixture(params=[0, 1])
def parametrized_name(request, name):
    return name


def test_something(parametrized_name):
    print "Testing with name: " + str(parametrized_name)

如果你进行上述测试,你会得到两个不同的名字"夹具

$ pytest -s blah.py
============================================= test session starts ==============================================
platform linux2 -- Python 2.7.14, pytest-3.3.2, py-1.5.2, pluggy-0.6.0
rootdir: /home/bsquizza/repos/blah/tests, inifile:
collected 2 items                                                                                              

blah.py Testing with name: 7
.Testing with name: 10
.                                                                                               [100%]

=========================================== 2 passed in 0.01 seconds ===========================================