初始设置
假设您有一个简化的项目conftest.py
包含以下代码:
import pytest
def pytest_addoption(parser):
parser.addoption('--foo', action='store', dest='foo', default='bar',
help='--foo should be always bar!')
@pytest.fixture
def foo(request):
fooval = request.config.getoption('foo')
if fooval != 'bar':
raise ValueError('expected foo to be "bar"; "{}" provided'.format(fooval))
它添加了一个新的命令行参数--foo
和一个固定装置foo
返回传递的参数,或者bar
如果没有指定。如果除此之外还有什么bar
通过--foo
,夹具产生ValueError
.
例如,您可以像往常一样使用灯具
def test_something(foo):
assert foo == 'bar'
现在让我们测试一下该装置。
准备工作
在这个例子中,我们首先需要进行一些简单的重构。将夹具和相关代码移动到某个名为其他名称的文件中conftest.py
, 例如,my_plugin.py
:
# my_plugin.py
import pytest
def pytest_addoption(parser):
parser.addoption('--foo', action='store', dest='foo', default='bar',
help='--foo should be always bar!')
@pytest.fixture
def foo(request):
fooval = request.config.getoption('foo')
if fooval != 'bar':
raise ValueError('expected foo to be "bar"; "{}" provided'.format(fooval))
In conftest.py
,确保新插件已加载:
# conftest.py
pytest_plugins = ['my_plugin']
运行现有的测试套件以确保我们没有破坏任何东西,所有测试仍然应该通过。
启用pytester
pytest
提供了一个额外的插件用于编写插件测试,称为pytester
。默认情况下它不会激活,因此您应该手动执行此操作。在conftest.py
,扩展插件列表pytester
:
# conftest.py
pytest_plugins = ['my_plugin', 'pytester']
编写测试
Once pytester
处于活动状态,您将获得一个名为testdir
。它可以生成并运行pytest
来自代码的测试套件。我们的第一个测试如下所示:
# test_foo_fixture.py
def test_all_ok(testdir):
testdata = '''
def test_sample(foo):
assert True
'''
testconftest = '''
pytest_plugins = ['my_plugin']
'''
testdir.makeconftest(testconftest)
testdir.makepyfile(testdata)
result = testdir.runpytest()
result.assert_outcomes(passed=1)
这里发生的事情应该非常明显:我们以字符串形式提供测试代码,testdir
将生成一个pytest
从它的项目到某个临时目录。为确保我们的foo
Fixture 在生成的测试项目中可用,我们将其传递到生成的测试项目中conftest
和我们在真人中做的一样。testdir.runpytest()
开始测试运行,产生我们可以检查的结果。
让我们添加另一个测试来检查是否foo
将提出一个ValueError
:
def test_foo_valueerror_raised(testdir):
testdata = '''
def test_sample(foo):
assert True
'''
testconftest = '''
pytest_plugins = ['my_plugin']
'''
testdir.makeconftest(testconftest)
testdir.makepyfile(testdata)
result = testdir.runpytest('--foo', 'baz')
result.assert_outcomes(errors=1)
result.stdout.fnmatch_lines([
'*ValueError: expected foo to be "bar"; "baz" provided'
])
在这里我们执行生成的测试--foo baz
并随后验证一项测试是否以错误结束,并且错误输出是否包含预期的错误消息。