#python-3.x #pytest
Вопрос:
Я ищу способ более элегантно расположить светильники pytest.
Прямо сейчас мой тестовый каталог выглядит так:
.
└── test
└── cli
├── test_compile.py
└── testdata
└── ...
В test_compile у меня есть серия тестов, в каждом из которых в качестве входных данных используется приспособление (строка). Прямо сейчас я выкладываю все многострочные строки в нижней части файла. Итак, это выглядит так:
def test_parse_zero_steps():
_testStep(1, 1, py_zero_steps, "ZERO_STEPS")
py_zero_steps = """
# ---
foo = "bar"
#
import tensorflow
"""
_testStep
это внутренняя функция, которой я передаю ряд параметров, чтобы подтвердить, правильно ли я проанализировал большой двоичный объект.
Это уже довольно громоздко, и у меня есть более 20 строк, которые мне нужно использовать здесь для тестирования крайних случаев. Есть ли элегантный/более питонический способ сделать это? Я посмотрел на параметризацию (https://docs.pytest.org/en/6.2.x/example/parametrize.html) что выглядит намного приятнее, но все еще не ясно, что я должен делать с этими большими/раздражающими строками. Поместить их все в свои собственные отдельные файлы?
Комментарии:
1. Есть ли какая-либо причина, по которой вы не смогли бы поместить многострочную строку в сам тестовый случай? например, например
python def test_input_1(input): expected = ''' # --- foo = "bar" # import tensorflow ''' actual = some_py_call(input) assert actual == expected
2. о, конечно, но это затрудняет редактирование (при необходимости — маловероятно, но возможно) и делает серию тестов очень шумной для просмотра. Некоторые многострочные строки являются строками реального мира и могут быть довольно большими (~2000 символов и более).
Ответ №1:
Предполагая , что все ваши тесты будут просто вызываться _testSteps
, лучший способ сделать это, вероятно, использовать parametrize
, как уже упоминалось в вопросе. Тестовые данные могут быть в отдельном файле, либо в виде переменной или функции Python, либо в виде файла json (или в каком-либо другом формате), который может быть прочитан parametrize
.
Вот простой пример использования функции Python:
def params():
return [
(
1, 1, """
# ---
foo = "bar"
#
import tensorflow
""",
"ZERO_STEPS"
),
(
1, 2, """
# something sensible
""",
"ONE_STEP"
),
...
]
Это может быть использовано в parametrize
:
@pytest.mark.parametrize("arg1, arg2, text, name", params(),
ids=[p[3] for p in params()])
def test_parse(arg1, arg2, text, name):
_testStep(arg1, arg2, text, name)
Это выводит что-то вроде:
$ pytest -vv
...
test_steps.py::test_parse[ZERO_STEPS] PASSED
test_steps.py::test_parse[ONE_STEP] PASSED
Обратите внимание, что я установил идентификаторы тестов name
в качестве аргумента, чтобы избежать нечитаемых имен тестов. Это всего лишь пример, но имеет смысл адаптироваться ids
из-за длинных строк. Без этого результат выглядел бы примерно так:
test_steps.py::test_parse[1-1-n# ---nnfoo = "bar"nn# nimport tensorflown-ZERO_STEPS] PASSED
test_steps.py::test_parse[1-2-n# something sensiblen-ONE_STEP] PASSED
что не совсем читаемо.