Как распечатать на консоли в 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
по другим причинам.
Кто-нибудь знает, как заставить показывать операторы печати?
Ответы
Ответ 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
может выполнять захват:
-
захват уровня дескриптора файла (FD) (по умолчанию): все записи, поступающие в дескрипторы файлов операционной системы 1 и 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