#python #yaml #pytest #doctest
#python #yaml #pytest #doctest
Вопрос:
Я использую doctest для тестирования фрагментов кода в файлах .rst. Во многих случаях наиболее важными тестами являются простые проверки достоверности конфигураций yaml.
Например:
>>> my_yaml = """
... foo:
... bar:
... - baz1
... - baz2
... """
>>> my_yaml_dict = yaml.load(my_yaml_string, Loader=yaml.FullLoader)
>>> assert "baz_2" in my_yaml_dict["foo"]["bar"]
Чтобы сделать код более читаемым и доступным для копирования, я бы хотел отобразить только блок yaml, а сам тест поместить в скрытый блок кода.
Это работает:
>>> my_yaml = """
... foo:
... bar:
... - baz1
... - baz2
... """
.. invisible-code-block: python
>>> my_yaml_dict = yaml.load(my_yaml_string, Loader=yaml.FullLoader)
>>> assert "baz_2" in my_yaml_dict["foo"]["bar"]
Однако блок yaml все еще инкапсулирован my_yaml="""..."""
, что затрудняет копирование и вставку.
Есть ли способ обрабатывать сам кодовый блок как переменную? Я представляю что-то в этом роде:
.. code-block:: yaml # doctest: varname=my_yaml_string
foo:
bar:
- baz1
- baz2
.. invisible-code-block: python
>>> my_yaml_dict = yaml.load(my_yaml_string, Loader=yaml.FullLoader)
>>> assert "baz_2" in my_yaml_dict["foo"]["bar"]
Ответ №1:
Основываясь на документации, я не думаю, что изменение / пропуск разделителей строки документа ( >>>
и ...
) возможно:
Любой ожидаемый результат должен немедленно следовать за последней строкой «>>>» или «…», содержащей код, а ожидаемый результат (если таковой имеется) распространяется на следующую строку «>>>» или всю строку с пробелами. https://docs.python.org/3/library/doctest.html#how-are-docstring-examples-recognized
Альтернативным решением может быть перемещение указанных данных Yaml во внешнюю переменную, переменную, которая не определена в блоке doctest:
my_yaml_string = """
foo:
bar:
- baz1
- baz2
"""
Вышеуказанная переменная может быть использована непосредственно из блока doctest:
>>> my_yaml_dict = yaml.load(my_yaml_string, Loader=yaml.FullLoader)
>>> assert "baz_2" in my_yaml_dict["foo"]["bar"]
Кроме my_yaml_string
того, переменная может быть определена в другом модуле, чтобы не влиять на производительность во время выполнения:
>>> import test_constants
>>> my_yaml_dict = yaml.load(test_constants.my_yaml_string, Loader=yaml.FullLoader)
>>> assert "baz_2" in my_yaml_dict["foo"]["bar"]
Кроме того, тестовые данные могут быть полностью перенесены в отдельный файл. Дополнительным преимуществом этого является включение покрытия статического анализатора для выбранного языка сериализации данных (в данном случае Yaml):
# test_data.yaml
foo:
bar:
- baz1
- baz2
>>> my_yaml_dict = yaml.load(open("test_data.yaml"), Loader=yaml.FullLoader)
>>> assert "baz_2" in my_yaml_dict["foo"]["bar"]
Обратите внимание, что это "test_data.yaml"
может потребоваться преобразовать в абсолютный путь, в зависимости от того, как выполняются doctests .
Комментарии:
1. Разделение тестовых данных на другие файлы выглядит многообещающе. Я попробую. Спасибо!