【问题标题】:Pytest use same fixture twice in one functionPytest 在一个函数中使用相同的夹具两次
【发布时间】:2016-07-06 03:59:50
【问题描述】:

对于我的 Web 服务器,我有一个 login 固定装置,它创建一个用户并返回发送请求所需的标头。对于某个测试,我需要两个用户。如何在一个功能中使用两次相同的夹具?

from test.fixtures import login


class TestGroups(object):

    def test_get_own_only(self, login, login):
         pass

【问题讨论】:

  • 由于固定装置是按功能缓存的,我看不出有一种简单的方法可以做到这一点。我想最好的解决方案是有一个_login 函数,然后是一个login1login2 夹具,它们都只是做return _login() 左右。

标签: python dependency-injection pytest fixtures


【解决方案1】:

另一种方法是复制夹具功能。这既简单又能正确处理参数化的夹具,使用两个夹具的所有参数组合调用测试函数。下面的示例代码引发了 9 个断言:

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)

【讨论】:

  • 很遗憾,如果 first 通过它所依赖的夹具进行参数化,这将无济于事。
【解决方案2】:

我使用Dummy 类来实现夹具功能。然后从你的测试中调用它。提供明确的方法名称以更好地了解您的测试在做什么。

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】:

    诀窍是使用带有“间接”开关的 mark.parametrize,因此:

    @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}]
    

    【讨论】:

      【解决方案4】:

      我需要我的测试直接调用一个夹具来覆盖当前的实例化结果,所以我编写了一个抽象层,其中包含对我所有夹具的引用:

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

      用(get_session 是另一个夹具)调用:

      call_fixture('fixture_name', get_session)
      

      【讨论】:

        【解决方案5】:

        我是这样做的:

        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
            ...
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-05-31
          • 2018-11-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-02-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多