Як я можу бачити нормальний вихід друку, створений під час запуску pytest?


400

Іноді мені хочеться просто вставити деякі заяви про друк у свій код і подивитися, що надрукується, коли я виконую це. Мій звичний спосіб "здійснити" це за допомогою існуючих тестів на пістери. Але коли я запускаю їх, я, здається, не бачу жодного стандартного виводу (принаймні, з PyCharm, моєї IDE).

Чи є простий спосіб побачити стандартний вихід під час запуску пітесту?


Тільки при невдачі чи завжди?

17
-s відключає захоплення за тест
hpk42

3
@delnan - Я хотів би бачити його завжди
Des

Відповіді:


564

-sПеремикач відключає в-тест захоплення.


86
-s=--capture=no
варильні панелі

URL-адреса порушена. Можливо, це допоможе: docs.pytest.org/en/latest/capture.html
code_dredd

1
Це призводить до перемежування виводу з виходом Pytest. Напевно, ви хочете, щоб Pytest захоплював вихід, як зазвичай, і показував його, коли тести проходять, а також не вдається. Див stackoverflow.com/a/59156707/369977
pR0Ps

51

У upvoted коментар до загальноприйнятому відповідь , Джо запитує:

Чи є який-небудь спосіб надрукувати на консолі І захопити вихід, щоб він відображався у звіті за липень?

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

Папачі мавпи py.test робити що- небудь непідтримуване нетривіально. Чому? Тому що:

  • Більшість функцій py.test заблоковано за приватним _pytestпакетом, не призначеним для зовнішнього імпорту. Спроба зробити це, не знаючи, що ви робите, як правило, призводить до того, що публічний pytestпакет піднімає незрозумілі винятки під час виконання. Дякую багато, py.test. Дійсно міцна архітектура, яку ви там отримали.
  • Навіть якщо ви робите зрозуміти, як мавпа-патч приватного _pytestAPI безпечним чином, ви повинні зробити це перш , ніж запустити публічний pytestзапуск пакету зовнішньої py.testкоманди. Це не можна робити в плагіні (наприклад, conftestмодуль верхнього рівня у вашому тестовому наборі). На той час py.test ліниво отримує навколо , щоб динамічно імпортувати плагін, будь py.test клас ви хотіли мавпячого патч вже давно був створений екземпляр - і ви НЕ маєте доступу до цього примірника. Це означає, що, якщо ви хочете, щоб ваш мавп-патч був змістовно застосований, ви більше не можете безпечно виконувати зовнішню py.testкоманду. Замість цього вам потрібно завершити виконання цієї команди спеціальними налаштуваннямиtest команда що (для порядку):
    1. Мавпа виправляє приватний _pytestAPI.
    2. Викликає функцію public pytest.main()для запуску py.testкоманди.

Ця відповідь мавпи-патчі py.test -sта --capture=noваріанти захоплення stderr, але не stdout. За замовчуванням ці параметри не охоплюють ні stderr, ні stdout. Звичайно, це не зовсім підлітково. Але кожна велика подорож починається з виснажливого приквелу, який всі забувають за п’ять років.

Навіщо це робити? Я зараз вам скажу. Мій тестовий набір py.test містить повільні функціональні тести. Відображення складності цих тестів є корисним та заспокійливим, не даючи лейчеку досягти, killall -9 py.testколи черговий тривалий функціональний тест не може нічого робити протягом тижнів. Однак відображення більш жорсткого рівня цих тестів не дозволяє py.test повідомляти про відстеження виключень щодо відмов тесту. Що зовсім непомітно. Отже, ми примушуємо py.test захоплювати stderr, але не stdout.

Перш ніж ми дістанемося до цього, ця відповідь передбачає, що у вас вже є спеціальна testкоманда setuptools, яка викликає py.test. Якщо ви цього не зробите, см Керівництва по інтеграції підрозділу добре написаного py.test в Належної практики сторінки.

Ви НЕ встановлювати pytest-бігун , сторонні Setuptools плагін Рекомендований Setuptools testкоманда також застосування py.test. Якщо pytest-runner вже встановлений, вам, ймовірно, потрібно буде видалити цей пакет pip3, а потім застосувати підключений до цього підхід вручну.

Якщо припустити, що ви дотримувались інструкцій у ручній інтеграції, зазначених вище, тепер ваша кодова база повинна містити 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, буде захоплено. Вишуканий!

Подовження вищевказаного патча на мавпу до трійкового вистрибування та стридер залишається читачеві як вправа з повним вільним часом барелем.


33

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

py.test exampletest.py -s

31

Згідно з документацією на 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')

20

pytest захоплює stdout з окремих тестів і відображає їх лише за певних умов разом із підсумком тестів, які він друкує за замовчуванням.

Додаткова підсумкова інформація може бути показана за допомогою параметра '-r':

pytest -rP

показує захоплений вихід пройдених тестів.

pytest -rx

показує знятий вихід невдалих тестів (поведінка за замовчуванням).

Форматування виводу красивіше з -r, ніж з -s.


2
Це фактична відповідь, яку я шукав! Дякую. (Після того, як stdout прийде ПІСЛЯ бажаних результатів тесту. Коли вони перемежовуються, друковані рядки втрачають значення.)
bossylobster

18

Спробуйте pytest -s -v test_login.pyотримати більше інформації в консолі.

-v це короткий --verbose

-s означає "відключити все захоплення"




1
якщо ви використовуєте файл pytest.ini, ви можете використовувати: addopts = -s -v python_files = test_login.py
timj98

4

Якщо ви використовуєте PyCharm IDE, ви можете запустити цей індивідуальний тест або всі тести за допомогою панелі інструментів Run. У вікні інструмента «Запуск» відображається результат, створений вашою програмою, і ви можете бачити всі виводи друку там, як частину тестового виводу.


Чи знаєте ви, як зробити друк PyCharm під час запуску тесту? (замість того, як пройшов тест)
Олександр Хуат

3

pytest --capture=tee-sysнещодавно додано. Ви можете зробити захоплення, а також побачити вихід на stdout / err.


-4

Інші відповіді не працюють. Тільки спосіб побачити захоплений вихід використовує наступний прапор:

pytest - шоу-захоплення всіх


6
--show-capture=all- це значення за замовчуванням. Додавання цього нічого не впливає.
гофлінг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.