首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何测试pytest fixture本身?

如何测试pytest fixture本身?
EN

Stack Overflow用户
提问于 2019-06-17 20:45:48
回答 1查看 2K关注 0票数 10

用什么方法来测试这个最小的夹具本身。请不要将其与在测试中使用fixture混淆。我只想自己测试fixture的正确性。

当我试图在测试中调用和执行它们时:

Fixture "app" called directly. Fixtures are not meant to be called directly

任何关于这方面的意见都将受到感谢。关于这个主题的文档没有给我提供有意义的指导:https://docs.pytest.org/en/latest/deprecations.html#calling-fixtures-directly

测试fixture本身的动机来自于我,因为当我们的测试由于fixture中的bug而失败时,在我们的TAP文件中没有被正确跟踪,是什么促使我单独测试fixture。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-18 00:16:19

pytest有一个pytester插件,用于测试pytest本身和插件;它在独立的运行中执行测试,不会影响当前的测试运行。示例:

代码语言:javascript
复制
# conftest.py

import pytest

pytest_plugins = ['pytester']

@pytest.fixture
def spam(request):
    yield request.param

fixture spam有一个问题,它只适用于参数化测试;一旦在非参数化测试中请求它,它就会引发AttributeError。这意味着我们不能通过像这样的常规测试来测试它:

代码语言:javascript
复制
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

相反,我们使用pytester插件提供的testdir fixture在隔离的测试运行中执行测试:

代码语言:javascript
复制
import pathlib
import pytest


# an example on how to load the code from the actual test suite
@pytest.fixture
def 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中设置根路径,例如:

代码语言:javascript
复制
[pytest]
pytester_example_dir = samples_for_fixture_tests
norecursedirs = samples_for_fixture_tests

现在创建包含以下内容的文件samples_for_fixture_tests/test_spam_fixture/test_x.py

代码语言:javascript
复制
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的代码相同)。以上测试更改为:

代码语言:javascript
复制
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标记配置测试数据根:

代码语言:javascript
复制
@pytest.mark.pytester_example_path('fizz')
def test_fizz(testdir):
    testdir.copy_example('buzz.txt')

将查找相对于项目根目录的文件fizz/buzz.txt

有关更多示例,请务必查看pytest文档中的Testing plugins部分;此外,您可能会发现my other answer to pytest check How can I test if a pytest fixture raises an exception?很有帮助,因为它包含了该主题的另一个有效示例。我还发现直接学习Testdir非常有帮助,因为遗憾的是,pytest没有为它提供大量的文档,但代码几乎是自文档化的。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56631622

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档