Похоже, что проект pytest-json
уже не существует. Разработчик / владелец pytest-json-report
может это сказать (в разделе Сопутствующие инструменты по этой ссылке ).
pytest- json имеет несколько замечательных функций, но, похоже, не поддерживается . Я позаимствовал оттуда некоторые идеи и тестовые примеры.
Проект pytest-json-report
обрабатывает именно тот случай, который мне нужен: захват стандартного вывода из подпроцесса и его размещение в отчете JSON. Ниже приведен грубый пример этого:
import subprocess as sp
import pytest
import sys
import re
def specialAssertHandler(str, assertMessage):
# because pytest automatically captures stdout,stderr this is all that's needed
# when the report is generated, this will be in a field named "stdout"
print(str)
return assertMessage
def test_subProcessStdoutCapture():
# NOTE: if you're version of Python 3 is sufficiently mature, add text=True also
proc = sp.Popen(['find', '.', '-name', '*.json'], stdout=sp.PIPE)
# NOTE: I had this because on the Ubuntu I was using, this is the version of
# Python and the return of proc.stdout.read() is a binary object not a string
if sys.version[0] == 3 and sys.version[6]:
output = proc.stdout.read().decode()
elif sys.version[0] == 2:
# The other version of Python I'm using is 2.7.15, it's exceedingly frustrating
# that the Python language def changed so between 2 and 3. In 2, the output
# was already a string object
output = proc.stdout.read()
m = re.search('some string', output)
assert m is not None, specialAssertHandler(output, "did not find 'some string' in output")
При использовании вышеупомянутого pytest-json-report
полный вывод подпроцесса фиксируется инфраструктурой и помещается в вышеупомянутый отчет. Отрывок, показывающий это, приведен ниже:
{
"nodeid": "expirment_test.py::test_stdout",
"lineno": 25,
"outcome": "failed",
"keywords": [
"PyTest",
"test_stdout",
"expirment_test.py"
],
"setup": {
"duration": 0.0002694129943847656,
"outcome": "passed"
},
"call": {
"duration": 0.02718186378479004,
"outcome": "failed",
"crash": {
"path": "/home/afalanga/devel/PyTest/expirment_test.py",
"lineno": 32,
"message": "AssertionError: Expected to find always\nassert None is not None"
},
"traceback": [
{
"path": "expirment_test.py",
"lineno": 32,
"message": "AssertionError"
}
],
"stdout": "./.report.json\n./report.json\n./report1.json\n./report2.json\n./simple_test.json\n./testing_addition.json\n\n",
"longrepr": "..."
},
"teardown": {
"duration": 0.0004875659942626953,
"outcome": "passed"
}
}
Поле longrepr
содержит полный текст тестового примера, но в интересах краткости оно состоит из многоточия. В поле crash
помещается значение assertMessage
из моего примера. Это показывает, что можно помещать такие сообщения в отчет в момент возникновения, а не после обработки.
Я думаю, что можно «умно» справиться с этим, используя ловушку, на которую я ссылался в моем исходном вопросе pytest_exception_interact
. Если это так, я обновлю этот ответ демонстрацией.