Как проверить сам прибор Pytest? - PullRequest
5 голосов
/ 17 июня 2019

Как правильно тестировать сам прибор pytest.Пожалуйста, не путайте это с использованием прибора в тестах.Я хочу просто проверить правильность осветителей самостоятельно.

При попытке вызвать и выполнить их внутри теста я сталкиваюсь с:

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

Любые входные данные будутоценили.Документы по этой теме не дают мне значимого руководства: https://docs.pytest.org/en/latest/deprecations.html#calling-fixtures-directly

Мотивация для тестирования приборов сама приходит ко мне, потому что, когда наш тест не удался из-за ошибки в приборе, это не было правильно отслежено в нашей TAPфайлы, которые побудили меня протестировать приборы самостоятельно.

1 Ответ

2 голосов
/ 17 июня 2019

pytest имеет плагин pytester, созданный для тестирования самого pytest и плагинов; тесты выполняются изолированно, что не влияет на текущий тест. Пример:

# conftest.py

import pytest

pytest_plugins = ['pytester']

@pytest.fixture
def 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 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, например:

[pytest]
pytester_example_dir = samples_for_fixture_tests
norecursedirs = 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 не предоставляет для этого подробных документов, но код в значительной степени самодокументируется.

...