Как я могу видеть нормальный вывод печати, созданный во время прогона pytest?

Иногда я хочу просто вставлять некоторые инструкции печати в свой код и видеть, что распечатывается, когда я его использую. Мой обычный способ "осуществить" это с существующими испытаниями pytest. Но когда я запускаю их, я не вижу никакого стандартного вывода (по крайней мере, из PyCharm, моей IDE).

Есть ли простой способ увидеть стандартный вывод во время прогона pytest?

Ответ 1

Переключатель -s отключает захват для каждого теста.

Ответ 2

В одобренном комментарии к принятому ответу, Joe:

Есть ли способ распечатать на консоли И захватить вывод так, чтобы он показывался в отчете junit?

В UNIX это обычно называют teeing. В идеале, тие, а не захват, будет по умолчанию py.test. Не идеально, ни py.test, ни любой существующий сторонний плагин py.test(... который я знаю, во всяком случае) поддерживает teeing - несмотря на то, что Python тривиально поддерживает teeing вне коробки.

Monkey-patching py.test делать что-либо неподдерживаемое нетривиально. Зачем? Потому что:

  • Большинство функций py.test заблокированы за закрытым пакетом _pytest, который не предназначен для импорта извне. Попытка сделать это, не зная, что вы делаете, обычно приводит к тому, что общедоступный пакет pytest создает неясные исключения во время выполнения. Спасибо большое, py.test. Достаточно надежная архитектура, которую вы получили там.
  • Даже если вы выясните, как обезопасить частный _pytest API в безопасном режиме, вы должны сделать это, прежде чем запускать общедоступный пакет pytest, выполняемый внешней командой py.test. Вы не можете сделать это в плагине (например, в верхнем уровне conftest в вашем тестовом наборе). К тому моменту, когда py.test лениво обходит динамический импорт вашего плагина, любой класс py.test, который вы хотели использовать для обезьян-патча, уже давно создан, и у вас нет доступа к этому экземпляру. Это означает, что если вы хотите, чтобы ваш обезьян-патч был осмысленно применен, вы больше не можете безопасно запускать внешнюю команду py.test. Вместо этого вы должны завершить запуск этой команды с помощью специальной команды setuptools test, которая (по порядку):
    • Обезьяна - исправляет частный _pytest API.
    • Вызывает функцию public pytest.main() для запуска команды py.test.

В этом ответе обезьяны - исправления параметров py.test -s и --capture=no для захвата stderr, но не stdout. По умолчанию эти параметры не содержат ни stderr, ни stdout. Конечно, это не совсем тиин. Но каждое великое путешествие начинается с утомительного приквела, которого каждый забывает через пять лет.

Зачем? Я скажу вам сейчас. Мой тестовый набор, основанный на py.test, содержит медленные функциональные тесты. Отображение вывода этих тестов полезно и обнадеживает, предотвращая leycec от достижения killall -9 py.test, когда еще один долговременный функциональный тест ничего не может сделать неделями. Однако отображение stderr этих тестов не позволяет py.test сообщать об ошибках отслеживания ошибок при сбоях тестирования. Это совершенно бесполезно. Следовательно, мы принуждаем py.test к захвату stderr, но не к stdout.

Прежде чем перейти к нему, этот ответ предполагает, что у вас уже есть команда setuptools test, вызывающая py.test. Если вы этого не сделаете, см. Ручная интеграция в подразделе py.test, хорошо написанном Хорошая практика.

Не устанавливайте pytest-runner, сторонний плагин setuptools, предоставляющий настраиваемую команду setuptools test, также вызывающую py.test. Если pytest-runner уже установлен, вам, вероятно, потребуется удалить этот пакет pip3, а затем применить ручной подход, связанный с выше.

Предполагая, что вы выполнили приведенные выше инструкции в Manual Integration, ваша кодовая база теперь должна содержать метод PyTest.run_tests(). Измените этот метод, чтобы он напоминал:

class PyTest(TestCommand):
             .
             .
             .
    def run_tests(self):
        # Import the public "pytest" package *BEFORE* the private "_pytest"
        # package. While importation order is typically ignorable, imports can
        # technically have side effects. Tragicomically, that is the case here.
        # Importing the public "pytest" package establishes runtime
        # configuration required by submodules of the private "_pytest" package.
        # The former *MUST* always be imported before the latter. Failing to do
        # so raises obtuse exceptions at runtime... which is bad.
        import pytest
        from _pytest.capture import CaptureManager, FDCapture, MultiCapture

        # If the private method to be monkey-patched no longer exists, py.test
        # is either broken or unsupported. In either case, raise an exception.
        if not hasattr(CaptureManager, '_getcapture'):
            from distutils.errors import DistutilsClassError
            raise DistutilsClassError(
                'Class "pytest.capture.CaptureManager" method _getcapture() '
                'not found. The current version of py.test is either '
                'broken (unlikely) or unsupported (likely).'
            )

        # Old method to be monkey-patched.
        _getcapture_old = CaptureManager._getcapture

        # New method applying this monkey-patch. Note the use of:
        #
        # * "out=False", *NOT* capturing stdout.
        # * "err=True", capturing stderr.
        def _getcapture_new(self, method):
            if method == "no":
                return MultiCapture(
                    out=False, err=True, in_=False, Capture=FDCapture)
            else:
                return _getcapture_old(self, method)

        # Replace the old with the new method.
        CaptureManager._getcapture = _getcapture_new

        # Run py.test with all passed arguments.
        errno = pytest.main(self.pytest_args)
        sys.exit(errno)

Чтобы включить этот патч обезьяны, запустите py.test следующим образом:

python setup.py test -a "-s"

Stderr, но не stdout теперь будет захвачен. Острота!

Расширение вышеперечисленного патча обезьяны на tee stdout и stderr оставлено в виде упражнения для читателя с полным свободным временем.

Ответ 3

При запуске теста используйте параметр -s. Все операторы печати в exampletest.py будут распечатаны на консоли при запуске теста.

py.test exampletest.py -s

Ответ 4

Согласно документации pytest, версия 3 pytest может временно отключить захват в тесте:

def test_disabling_capturing(capsys):
    print('this output is captured')
    with capsys.disabled():
        print('output not captured, going directly to sys.stdout')
    print('this output is also captured')

Ответ 5


Попробуйте pytest -s -v test_login.py для получения дополнительной информации в консоли.

-v это короткий --verbose

-s означает "отключить все записи".



Ответ 6

Если вы используете PyCharm IDE, то вы можете запустить этот отдельный тест или все тесты, используя панель инструментов "Выполнить". В окне инструмента Выполнить отображаются выходные данные, сгенерированные вашим приложением, и вы можете увидеть все операторы печати в них как часть результатов теста.

Ответ 7

Другие ответы не работают. Единственный способ увидеть захваченный вывод - использовать следующий флаг:

pytest - показать-захватить все

Ответ 8

pytest -v -s scriptname(for single test script)

pytest -v -s (for complete module/package)

pytest -v -s scriptname::function(indiviual function)