Pytest use same fixture twice in one function

2019-02-21 11:22发布

For my web server, I have a login fixture that create a user and returns the headers needed to send requests. For a certain test, I need two users. How can I use the same fixture twice in one function?

from test.fixtures import login


class TestGroups(object):

    def test_get_own_only(self, login, login):
         pass

5条回答
啃猪蹄的小仙女
2楼-- · 2019-02-21 11:30

I do it with Dummy class which will implement fixture functionality. Then just call it from your test. Provide clarify method name to better understand what is your test doing.

import pytest

@pytest.fixture
def login():
    class Dummy:
        def make_user(self):
            return 'New user name'
    return Dummy()

def test_something(login):
    a = login.make_user()
    b = login.make_user()
    assert a == b
查看更多
成全新的幸福
3楼-- · 2019-02-21 11:30

I needed my tests to directly call a fixture to overwrite the current instanced result, so I wrote an abstraction layer that contains references to all of my fixtures:

def call_fixture(fixture, session=''):
    return {
        'fixture_name': fixture_name(session),
    }[fixture]

Called with (get_session is another fixture):

call_fixture('fixture_name', get_session)
查看更多
看我几分像从前
4楼-- · 2019-02-21 11:32

An alternative is just to copy the fixture function. This is both simple and correctly handles parameterized fixtures, calling the test function with all combinations of parameters for both fixtures. This example code below raises 9 assertions:

import pytest

@pytest.fixture(params=[0, 1, 2])
def first(request):
    return request.param

second = first

def test_double_fixture(first, second):
    assert False, '{} {}'.format(first, second)
查看更多
来,给爷笑一个
5楼-- · 2019-02-21 11:39

I have done it like so:

limits = [10, 20, 30]

@pytest.fixture(params=limits)
def number(request):
    return random.randint(request.param)

@pytest.fixture(params=limits)
def two_numbers(request):
    return number(request), number(request)

def test_numbers(two_numbers):
    num_1, num_2 = two_numbers
    ...
查看更多
三岁会撩人
6楼-- · 2019-02-21 11:48

The trick is to use mark.parametrize with the "indirect" switch, thus:

@pytest.fixture
def data_repeated(request):
    return [deepcopy({'a': 1, 'b': 2}) for _ in range(request.param)]


@pytest.mark.parametrize('data_repeated', [3], indirect=['data_repeated'])
def test(data_repeated):
    assert data_repeated == [
        {'a': 1, 'b': 2},
        {'a': 1, 'b': 2},
        {'a': 1, 'b': 2}]
查看更多
登录 后发表回答