Подтвердить что ты не робот

Как распечатать на консоли в pytest?

Я пытаюсь использовать TDD (разработка через тестирование) с pytest. pytest не будет print на консоль, когда я использую print.

Я использую pytest my_tests.py для его запуска.

documentation говорит, что она должна работать по умолчанию: http://pytest.org/latest/capture.html

Но:

import myapplication as tum

class TestBlogger:

    @classmethod
    def setup_class(self):
        self.user = "alice"
        self.b = tum.Blogger(self.user)
        print "This should be printed, but it won't be!"

    def test_inherit(self):
        assert issubclass(tum.Blogger, tum.Site)
        links = self.b.get_links(posts)
        print len(links)   # This won't print either.

Ничего не выводится на мою стандартную консоль вывода (только обычный прогресс и сколько тестов пройдено/не выполнено).

И скрипт, который я тестирую, содержит print:

class Blogger(Site):
    get_links(self, posts):
        print len(posts)   # It won't get printed in the test.

В модуле unittest все печатается по умолчанию, и это именно то, что мне нужно. Тем не менее, я хочу использовать pytest по другим причинам.

Кто-нибудь знает, как заставить показывать операторы печати?

4b9b3361

Ответ 1

По умолчанию py.test фиксирует результат стандартного вывода, чтобы он мог контролировать, как он печатает его. Если бы это не сделало этого, это вылило бы много текста без контекста того, какой тест напечатал этот текст.

Однако, если тест завершится с ошибкой, он будет содержать раздел в результирующем отчете, который показывает, что было напечатано стандартным в этом конкретном тесте.

Например,

def test_good():
    for i in range(1000):
        print(i)

def test_bad():
    print('this should fail!')
    assert False

Результаты в следующем выпуске:

>>> py.test tmp.py
============================= test session starts ==============================
platform darwin -- Python 2.7.6 -- py-1.4.20 -- pytest-2.5.2
plugins: cache, cov, pep8, xdist
collected 2 items

tmp.py .F

=================================== FAILURES ===================================
___________________________________ test_bad ___________________________________

    def test_bad():
        print('this should fail!')
>       assert False
E       assert False

tmp.py:7: AssertionError
------------------------------- Captured stdout --------------------------------
this should fail!
====================== 1 failed, 1 passed in 0.04 seconds ======================

Обратите внимание на раздел Captured stdout.

Если вы хотите видеть операторы print по мере их выполнения, вы можете передать флаг -s на py.test. Однако обратите внимание, что это иногда бывает трудно разобрать.

>>> py.test tmp.py -s
============================= test session starts ==============================
platform darwin -- Python 2.7.6 -- py-1.4.20 -- pytest-2.5.2
plugins: cache, cov, pep8, xdist
collected 2 items

tmp.py 0
1
2
3
... and so on ...
997
998
999
.this should fail!
F

=================================== FAILURES ===================================
___________________________________ test_bad ___________________________________

    def test_bad():
        print('this should fail!')
>       assert False
E       assert False

tmp.py:7: AssertionError
====================== 1 failed, 1 passed in 0.02 seconds ======================

Ответ 2

С помощью параметра -s будет выводиться вывод всех функций, что может быть слишком большим.

Если вам нужен конкретный вывод, указанная вами страница документа предлагает несколько предложений:

  • Вставьте assert False, "dumb assert to make PyTest print my stuff" в конце вашей функции, и вы увидите ваш результат из-за неудачного теста.

  • У вас есть специальный объект, переданный вам PyTest, и вы можете записать вывод в файл, чтобы его проверить позже, например

    def test_good1(capsys):
        for i in range(5):
            print i
        out, err = capsys.readouterr()
        open("err.txt", "w").write(err)
        open("out.txt", "w").write(out)
    

    Вы можете открыть файлы out и err на отдельной вкладке и позволить редактору автоматически обновить его для вас или выполнить простую команду оболочки py.test; cat out.txt для запуска теста.

Это довольно хакерский способ делать вещи, но может быть, это то, что вам нужно: ведь TDD означает, что вы возитесь с вещами и оставляете его чистым и бесшумным, когда он готов: -).

Ответ 3

Мне нужно было напечатать важное предупреждение о пропущенных тестах, когда PyTest приглушено буквально все.

Я не хотел проваливать тест, чтобы отправить сигнал, поэтому я сделал взлом, как следует:

def test_2_YellAboutBrokenAndMutedTests():
    import atexit
    def report():
        print C_patch.tidy_text("""
In silent mode PyTest breaks low level stream structure I work with, so
I cannot test if my functionality work fine. I skipped corresponding tests.
Run `py.test -s` to make sure everything is tested.""")
    if sys.stdout != sys.__stdout__:
        atexit.register(report)

Модуль atexit позволяет мне печатать материал после того, как PyTest выпустил выходные потоки. Результат выглядит следующим образом:

============================= test session starts ==============================
platform linux2 -- Python 2.7.3, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: /media/Storage/henaro/smyth/Alchemist2-git/sources/C_patch, inifile: 
collected 15 items 

test_C_patch.py .....ssss....s.

===================== 10 passed, 5 skipped in 0.15 seconds =====================
In silent mode PyTest breaks low level stream structure I work with, so
I cannot test if my functionality work fine. I skipped corresponding tests.
Run `py.test -s` to make sure everything is tested.
~/.../sources/C_patch$

Сообщение печатается, даже если PyTest находится в тихом режиме и не печатается, если вы запускаете материал с помощью py.test -s, поэтому все прошло успешно.

Ответ 4

В соответствии с pytest docs, pytest --capture=sys должен работать. Если вы хотите выполнить стандартную проверку внутри теста, обратитесь к устройству capsys.

Ответ 5

Короткий ответ

Используйте -s:

pytest -s

Подробный ответ

Из документов:

Во время выполнения теста все выходные данные, отправленные на stdout и stderr, регистрируются Если тест или метод настройки не пройден, его соответствующий захваченный вывод обычно отображается вместе с отслеживанием ошибки.

pytest есть опция --capture=method в котором method является method захвата для каждого теста и может быть одним из следующих: fd, sys или no. pytest также есть опция -s которая является сокращением для --capture=no, и эта опция позволит вам видеть ваши операторы печати в консоли.

pytest --capture=no     # show print statements in console
pytest -s               # equivalent to previous command

Настройка методов захвата или отключение захвата

Есть два способа, которыми pytest может выполнять захват:

  1. захват уровня дескриптора файла (FD) (по умолчанию): все записи, поступающие в дескрипторы файлов операционной системы 1 и 2, будут перехвачены.

  2. Захват уровня sys: записываются только файлы Python: sys.stdout и sys.stderr. Захват записи в файловые дескрипторы не выполняется.

pytest -s            # disable all capturing
pytest --capture=sys # replace sys.stdout/stderr with in-mem files
pytest --capture=fd  # also point filedescriptors 1 and 2 to temp file