Работа с тестами не на Python
Простой пример описания тестов в YAML-файлах
Вот пример conftest.py (взятый из специального плагина pytest-yamlwsgi Али Афшара). Этот conftest.py будет собирать файлы test*.yaml и выполнять содержимое в формате YAML в качестве пользовательских тестов:
# content of conftest.py
from __future__ import annotations
import pytest
def pytest_collect_file(parent, file_path):
if file_path.suffix == ".yaml" and file_path.name.startswith("test"):
return YamlFile.from_parent(parent, path=file_path)
class YamlFile(pytest.File):
def collect(self):
# We need a yaml parser, e.g. PyYAML.
import yaml
raw = yaml.safe_load(self.path.open(encoding="utf-8"))
for name, spec in sorted(raw.items()):
yield YamlItem.from_parent(self, name=name, spec=spec)
class YamlItem(pytest.Item):
def __init__(self, *, spec, **kwargs):
super().__init__(**kwargs)
self.spec = spec
def runtest(self):
for name, value in sorted(self.spec.items()):
# Some custom test execution (dumb example follows).
if name != value:
raise YamlException(self, name, value)
def repr_failure(self, excinfo):
"""Called when self.runtest() raises an exception."""
if isinstance(excinfo.value, YamlException):
return "\n".join(
[
"usecase execution failed",
" spec failed: {1!r}: {2!r}".format(*excinfo.value.args),
" no further details known at this point.",
]
)
return super().repr_failure(excinfo)
def reportinfo(self):
return self.path, 0, f"usecase: {self.name}"
class YamlException(Exception):
"""Custom exception for error reporting."""
Можно создать простой файл-пример:
# test_simple.yaml
ok:
sub1: sub1
hello:
world: world
some: other
и, если установлен PyYAML или совместимый YAML-парсер, теперь можно выполнить спецификацию тестов:
nonpython $ pytest test_simple.yaml =========================== test session starts ============================ platform linux -- Python 3.x.y, pytest-9.x.y, pluggy-1.x.y rootdir: /home/sweet/project/nonpython collected 2 items test_simple.yaml F. [100%] ================================= FAILURES ================================= ______________________________ usecase: hello ______________________________ usecase execution failed spec failed: 'some': 'other' no further details known at this point. ========================= short test summary info ========================== FAILED test_simple.yaml::hello - usecase execution failed ======================= 1 failed, 1 passed in 0.12s ========================
Вы увидите одну точку за пройденную проверку sub1: sub1 и один сбой. Очевидно, что в приведённом выше conftest.py вам понадобится реализовать более интересную интерпретацию значений YAML. Таким способом можно легко создать собственный предметно-ориентированный язык тестирования.
Примечание
repr_failure(excinfo) вызывается для представления ошибок тестов. Если вы создаёте собственные узлы сбора, можно вернуть строковое представление ошибки по своему выбору. Оно будет показано в виде (красной) строки.
reportinfo() используется для представления расположения теста, а также учитывается при выводе отчётов в режиме verbose. Он должен возвращать кортеж (path, lineno, description), где:
-
path— путь, отображаемый в отчётах (обычноself.pathилиself.fspath). -
lineno— номер строки с отсчётом от нуля или0, если конкретная строка не указана. -
description— краткая метка, отображаемая для собранного элемента:
nonpython $ pytest -v =========================== test session starts ============================ platform linux -- Python 3.x.y, pytest-9.x.y, pluggy-1.x.y -- $PYTHON_PREFIX/bin/python cachedir: .pytest_cache rootdir: /home/sweet/project/nonpython collecting ... collected 2 items test_simple.yaml::hello FAILED [ 50%] test_simple.yaml::ok PASSED [100%] ================================= FAILURES ================================= ______________________________ usecase: hello ______________________________ usecase execution failed spec failed: 'some': 'other' no further details known at this point. ========================= short test summary info ========================== FAILED test_simple.yaml::hello - usecase execution failed ======================= 1 failed, 1 passed in 0.12s ========================
При разработке собственного механизма сбора и выполнения тестов также полезно посмотреть на дерево сбора:
nonpython $ pytest --collect-only
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-9.x.y, pluggy-1.x.y
rootdir: /home/sweet/project/nonpython
collected 2 items
<Package nonpython>
<YamlFile test_simple.yaml>
<YamlItem hello>
<YamlItem ok>
======================== 2 tests collected in 0.12s ========================
© 2015–2026 Holger Krekel and pytest-dev team
Licensed under the MIT License.
https://docs.pytest.org/en/stable/example/nonpython.html