Сценарий
Я пишу пакет, который требует от меня внешнего вызова pytest
из pytest
, запущенного через subprocess
.Таким образом, очевидно, что вывод, полученный из подпроцесса, является именно той ошибкой, которую я хочу отобразить, поскольку в ней есть все приятное форматирование и информация, которую предоставляет pytest.К сожалению, в настоящее время основной вызов pytest показывает только внутренний код моей обертки, а не симпатичный вывод подпроцесса, который после печати выводится только в захваченном разделе stdout pytest.Я хотел бы отформатировать вывод для сбоев и ошибок, как если бы код вызывался напрямую, и скрыть, что был сделан вызов подпроцесса.Следовательно, я хочу полностью заменить вывод для одной тестовой функции другой строкой.Возможно ли это?
MWE
Давайте рассмотрим MWE простой упакованной функции (не делающей ничего полезного, но самое короткое MWE, о котором я мог подумать):
import functools
import json
from subprocess import Popen, PIPE
import sys
def call_something(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
# for the sake of simplicity, a dummy call
p = Popen([sys.executable, '-c', 'import numby'], stderr=PIPE, stdout=PIPE)
# let's imagine this is the perfect string output we want
# to print instead of the actual output generated from...
error = p.communicate()[1].decode("utf-8")
if p.returncode != 0:
# ... this line
raise AssertionError(f'{error}')
return wrapper
@call_something
def test_something():
assert 1 == 2
Как вы можете видеть, у меня есть test_something()
функция, которая в подпроцессе завершится ошибкой.
Текущий вывод
Если я запускаю pytest
с этим файлом, я получаю:
================================== FAILURES ===================================
_______________________________ test_something ________________________________
func = <function test_something at 0x000001EA414F1400>, args = (), kwargs = {}
p = <subprocess.Popen object at 0x000001EA414A67B8>
error = 'Traceback (most recent call last):\r\n File "<string>", line 1, in <module>\r\nModuleNotFoundError: No module named \'numby\'\r\n'
def wrapper(*args, **kwargs):
# for the sake of simplicity, a dummy call
p = Popen([sys.executable, '-c', 'import numby'], stderr=PIPE, stdout=PIPE)
# let's imagine this is the perfect string output we want
# to print instead of the actual output generated from...
error = p.communicate()[1].decode("utf-8")
if p.returncode != 0:
# ... this line
> raise AssertionError(f'{error}')
E AssertionError: Traceback (most recent call last):
E File "<string>", line 1, in <module>
E ModuleNotFoundError: No module named 'numby'
test_me.py:18: AssertionError
========================== 1 failed in 0.18 seconds ===========================
Очевидно, я не хочу показывать детали функции оболочки,Вместо
Желаемый вывод
Я хотел бы показать, что происходит в подпроцессе.Вот так и должно выглядеть (или похоже).
================================== FAILURES ===================================
_______________________________ test_something ________________________________
<string captured from subprocess>
========================== 1 failed in 0.11 seconds ===========================
Так что мой вопрос в меньших битах:
Короче вопрос
- Как заменить pytestвывод для теста с пользовательской строкой из моей оболочки?