У upvoted коментар до загальноприйнятому відповідь , Джо запитує:
Чи є який-небудь спосіб надрукувати на консолі І захопити вихід, щоб він відображався у звіті за липень?
У UNIX це зазвичай називають підлітком . В ідеалі, за замовчуванням py.test буде замість захоплення, а не захоплення. Ні в ідеалі, ні py.test, ні будь-який сторонній плагін py.test (... який я знаю, все одно ) не підтримує сприятливе бажання - незважаючи на Python, який тривіально підтримує тенісинг поза коробкою .
Папачі мавпи py.test робити що- небудь непідтримуване нетривіально. Чому? Тому що:
- Більшість функцій py.test заблоковано за приватним
_pytest
пакетом, не призначеним для зовнішнього імпорту. Спроба зробити це, не знаючи, що ви робите, як правило, призводить до того, що публічний pytest
пакет піднімає незрозумілі винятки під час виконання. Дякую багато, py.test. Дійсно міцна архітектура, яку ви там отримали.
- Навіть якщо ви робите зрозуміти, як мавпа-патч приватного
_pytest
API безпечним чином, ви повинні зробити це перш , ніж запустити публічний pytest
запуск пакету зовнішньої py.test
команди. Це не можна робити в плагіні (наприклад, conftest
модуль верхнього рівня у вашому тестовому наборі). На той час py.test ліниво отримує навколо , щоб динамічно імпортувати плагін, будь py.test клас ви хотіли мавпячого патч вже давно був створений екземпляр - і ви НЕ маєте доступу до цього примірника. Це означає, що, якщо ви хочете, щоб ваш мавп-патч був змістовно застосований, ви більше не можете безпечно виконувати зовнішню py.test
команду. Замість цього вам потрібно завершити виконання цієї команди спеціальними налаштуваннямиtest
команда що (для порядку):
- Мавпа виправляє приватний
_pytest
API.
- Викликає функцію 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, буде захоплено. Вишуканий!
Подовження вищевказаного патча на мавпу до трійкового вистрибування та стридер залишається читачеві як вправа з повним вільним часом барелем.