Как получить название теста и результат теста во время выполнения в pytest
Я хочу получить имя теста и результат теста во время выполнения.
я имею setup
а также tearDown
методы в моем сценарии. В setup
Мне нужно получить название теста, а в tearDown
Мне нужно получить результат теста и время выполнения теста.
Есть ли способ, которым я могу сделать это?
4 ответа
Вы можете, используя крючок.
У меня есть эти файлы в моей тестовой директории:
./rest/
├── conftest.py
├── __init__.py
└── test_rest_author.py
В test_rest_author.py
У меня есть три функции, startup
, teardown
а также test_tc15
, но я только хочу показать результат и имя для test_tc15
,
Создать conftest.py
файл, если у вас его еще нет, и добавьте это:
import pytest
from _pytest.runner import runtestprotocol
def pytest_runtest_protocol(item, nextitem):
reports = runtestprotocol(item, nextitem=nextitem)
for report in reports:
if report.when == 'call':
print '\n%s --- %s' % (item.name, report.outcome)
return True
Крюк pytest_runtest_protocol
реализует протокол runtest_setup / call / teardown для данного тестового элемента, включая захват исключений и вызов ловушек отчетности. Вызывается, когда заканчивается любой тест (например, startup
или же teardown
или твой тест).
Если вы запустите свой скрипт, вы увидите результат и название теста:
$ py.test ./rest/test_rest_author.py
====== test session starts ======
/test_rest_author.py::TestREST::test_tc15 PASSED
test_tc15 --- passed
======== 1 passed in 1.47 seconds =======
Также смотрите документацию по крюкам pytest и conftest.py.
unittest.TestCase.id() возвращает полную информацию, включая имя класса, имя метода. Из этого мы можем извлечь имя метода тестирования. Получить результаты можно, проверив, есть ли исключения при выполнении теста. Если тест не пройден, тогда будет исключение, если sys.exc_info() вернет None, тогда тест пройден, иначе тест будет неудачным.
могу предложить еще один способ. Определите атрибут отчета для каждого теста в pytest_runtest_makereport, после этого используйте его в любом приспособлении. Имя теста также доступно в любой момент с помощью os.environ.get('PYTEST_CURRENT_TEST')
содержимое conftest.py
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item):
report = (yield).get_result()
if not getattr(item, 'report', None) or not report.passed:
setattr(item, 'report', report)
@pytest.fixture(scope='function')
def any_fixture(request):
print(f"test name in setup {os.environ.get('PYTEST_CURRENT_TEST')}")
yield
print(f"test name in teardown {os.environ.get('PYTEST_CURRENT_TEST')}")
print(f"{request.node.report.failed=}")
print(f"{request.node.report.duration=}")
содержание любого теста
class TestClass:
def test_body(self, any_fixture):
print(f"test name in test body {os.environ.get('PYTEST_CURRENT_TEST')}")
выход:
test name in setup tests/unknown/test_check.py::TestClass::test_body (setup)
test name in test body tests/unknown/test_check.py::TestClass::test_body (call)
test name in teardown tests/unknown/test_check.py::TestClass::test_body (teardown)
request.node.report.failed=False
request.node.report.duration=0.0006430509999999501
С помощью pytest_runtest_protocol
как было предложено с помощью маркера приспособления, я решил мою проблему. В моем случае достаточно было просто использоватьreports = runtestprotocol(item, nextitem=nextitem)
в моем приспособлении pytest html. Итак, чтобы завершитьitem
Элемент содержит нужную вам информацию.
Огромное спасибо.