pytest有一个
pytester用于测试
pytest自身和插件的插件;它在不影响当前测试运行的隔离运行中执行测试。例:
# conftest.pyimport pytestpytest_plugins = ['pytester']@pytest.fixturedef spam(request): yield request.param
固定装置
spam有一个问题,它仅适用于参数化测试;一旦在非参数化测试中提出要求,它将引发
AttributeError。这意味着我们不能通过这样的常规测试来测试它:
def test_spam_no_params(spam): # too late to verify anything - spam already raised in test setup! # In fact, the body of this test won't be executed at all. pass
相反,我们使用插件
testdir提供的夹具在隔离的测试运行中执行测试
pytester:
import pathlibimport pytest# an example on how to load the pre from the actual test suite@pytest.fixturedef read_conftest(request): return pathlib.Path(request.config.rootdir, 'conftest.py').read_text()def test_spam_fixture(testdir, read_conftest): # you can create a test suite by providing file contents in different ways, e.g. testdir.makeconftest(read_conftest) testdir.makepyfile( """ import pytest @pytest.mark.parametrize('spam', ('eggs', 'bacon'), indirect=True) def test_spam_parametrized(spam): assert spam in ['eggs', 'bacon'] def test_spam_no_params(spam): assert True""") result = testdir.runpytest() # we should have two passed tests and one failed (unarametrized one) result.assert_outcomes(passed=3, error=1) # if we have to, we can analyze the output made by pytest assert "AttributeError: 'SubRequest' object has no attribute 'param'" in ' '.join(result.outlines)该
testdir.copy_example方法是为测试加载测试代码的另一个方便方法。在中设置根路径
pytest.ini,例如:
[pytest]pytester_example_dir = samples_for_fixture_testsnorecursedirs = samples_for_fixture_tests
现在创建
samples_for_fixture_tests/test_spam_fixture/test_x.py包含以下内容的文件:
import pytest@pytest.mark.parametrize('spam', ('eggs', 'bacon'), indirect=True)def test_spam_parametrized(spam): assert spam in ['eggs', 'bacon']def test_spam_no_params(spam): assert True(与作为字符串传递到
testdir.makepyfile之前的代码相同)。以上测试更改为:
def test_spam_fixture(testdir, read_conftest): testdir.makeconftest(read_conftest) # pytest will now copy everything from samples_for_fixture_tests/test_spam_fixture testdir.copy_example() testdir.runpytest().assert_outcomes(passed=3, error=1)
这样,您就不必在测试中将Python代码维护为字符串,也可以通过使用运行它们来重用现有的测试模块
pytester。您还可以通过
pytester_example_path标记配置测试数据根:
@pytest.mark.pytester_example_path('fizz')def test_fizz(testdir): testdir.copy_example('buzz.txt')将查找
fizz/buzz.txt相对于项目根目录的文件。
更多的例子,肯定检查了部分测试插件的
pytest文档;
另外,您可能会找到我对问题的其他答案,我该如何测试pytest固定装置是否引发异常?很有帮助,因为它包含了该主题的另一个有效示例。我还发现直接研究
Testdir代码非常有帮助,因为遗憾的
pytest是它没有提供详尽的文档,但是代码几乎可以自我记录。



