在py.test中,将夹具标记为夹具有什么意义?

时间:2017-10-09 20:48:44

标签: python pytest

import pytest

@pytest.fixture()
def my_fixture():
    data = {'x': 1, 'y': 2, 'z': 3}
    return data

def test_my_fixture(my_fixture):
    assert my_fixture['x'] == 1

my_fixture标记为pytest fixture有什么好处?似乎夹具的好处与my_fixture只是正常功能相同,删除装饰器。

我仅在此处看到了my_fixture运行{1}}的好处,只需将其作为test_my_fixture的参数提供:

@pytest.fixture()
def my_fixture():
    print "\nI'm the fixture"

def test_my_fixture(my_fixture):
    print "I'm the test"

这应该打印:

I'm the fixture
I'm the test

1 个答案:

答案 0 :(得分:6)

如果您没有将my_fixture声明为灯具,那么测试将无法将其用作灯具:

import pytest

def my_fixture():
    data = {'x': 1, 'y': 2, 'z': 3}
    return data

def test_my_fixture(my_fixture):
    assert my_fixture['x'] == 1

此脚本会导致错误:

  def test_my_fixture(my_fixture):
E       fixture 'my_fixture' not found
>       available fixtures: cache, capfd, capsys, doctest_namespace, monkeypatch, pytestconfig, record_xml_property, recwarn, tmpdir, tmpdir_factory
>       use 'pytest --fixtures [testpath]' for help on them.

灯具的目的是在测试之前准备一些东西。并在之后杀死它。而不是参与测试(例如,在日志记录,报告,异常处理方式等)。它是一种先决条件,由其他东西创造,并且只是给予测试。

如果您只是将其声明为函数,并将其用作函数,则它是一个函数,而不是一个fixture。它的失败成为测试的失败,而不是一般的框架运行。

考虑这个例子:

import pytest

@pytest.fixture()
def my_fixture():
    data = {'x': 1, 'y': 2, 'z': 3}
    print('prepare')
    yield data
    print('destroy')

def test_my_fixture(my_fixture):
    print('test it')
    assert my_fixture['x'] == 1

同样在此示例中,尝试取消注释提升线,并查看差异。它将是ERROR与FAILURE。对于以后如何解释和处理测试结果至关重要(例如,由开发人员,QA工程师或分析测试结果的人员)。

import pytest

@pytest.fixture()
def my_fixture():
    print('prepare')
    # raise Exception('Oops')
    yield None
    print('destroy')

def test_my_fixture(my_fixture):
    # raise Exception('Booms!')
    print('test it')

在灯具中:

======================================= test session starts ========================================
collected 1 item                                                                                    

t.py E

============================================== ERRORS ==============================================
________________________________ ERROR at setup of test_my_fixture _________________________________

    @pytest.fixture()
    def my_fixture():
        data = {'x': 1, 'y': 2, 'z': 3}
        print('prepare')
>       raise Exception('Oops')
E       Exception: Oops

t.py:7: Exception
===================================== 1 error in 0.03 seconds ======================================

在测试或从测试调用的任何函数中:

======================================= test session starts ========================================
collected 1 item                                                                                    

t.py F

============================================= FAILURES =============================================
_________________________________________ test_my_fixture __________________________________________

my_fixture = {'x': 1, 'y': 2, 'z': 3}

    def test_my_fixture(my_fixture):
>       raise Exception('Booms!')
E       Exception: Booms!

t.py:12: Exception
===================================== 1 failed in 0.03 seconds =====================================

另请注意,灯具具有范围:会话,模块,功能。在一个简短的例子中很难证明,但在这种情况下,夹具只能准备和销毁一次(通常只有一次),以便在该范围内进行多次测试。这对于重型夹具很重要,例如数据库预填充。这样的装置通常驻留在目录结构中的conftest.py伪插件中(注意:这不是要导入的常规模块!至少在设计上)。