Функция тестирования Мне нужно передать параметры и увидеть, что результат соответствует ожидаемому результату.
Легко, когда ответ функции - это просто малый массив или однострочная строка, которая может быть определена внутри тестовой функции, но предположим, что функция я test изменяет файл конфигурации, который может быть огромным. Или результирующий массив имеет длину 4 строки, если я определяю его явно. Где я могу хранить это, поэтому мои тесты остаются чистыми и легкими в обслуживании?
Прямо сейчас, если это строка, я просто помещаю файл рядом с тестом .py
и выполняю open()
внутри теста:
def test_if_it_works():
with open('expected_asnwer_from_some_function.txt') as res_file:
expected_data = res_file.read()
input_data = ... # Maybe loaded from a file as well
assert expected_data == if_it_works(input_data)
Я вижу много проблем с таким подходом, как проблема поддержания этого файла в актуальном состоянии. Это выглядит плохо. Я могу сделать вещи, вероятно, лучше, переместив это на приспособление:
@pytest.fixture
def expected_data()
with open('expected_asnwer_from_some_function.txt') as res_file:
expected_data = res_file.read()
return expected_data
@pytest.fixture
def input_data()
return '1,2,3,4'
def test_if_it_works(input_data, expected_data):
assert expected_data == if_it_works(input_data)
Это просто переводит проблему в другое место, и обычно мне нужно проверить, работает ли функция в случае пустого ввода, ввода одного элемента или нескольких элементов, поэтому я должен создать одно большое приспособление, включающее все три случая или несколько приборов. В конце код становится довольно грязным.
Если функция ожидает сложный словарь в качестве ввода или возвращает словарь того же самого большого тестового кода размера, он становится уродливым:
@pytest.fixture
def input_data():
# It just an example
return {['one_value': 3, 'one_value': 3, 'one_value': 3,
'anotherky': 3, 'somedata': 'somestring'],
['login': 3, 'ip_address': 32, 'value': 53,
'one_value': 3], ['one_vae': 3, 'password': 13, 'lue': 3]}
Сложно читать тесты с такими приборами и поддерживать их в актуальном состоянии.
Update
После некоторого поиска я нашел библиотеку, которая решила часть проблемы, когда вместо больших файлов конфигурации у меня были большие ответы HTML. Это betamax.
Для упрощения использования я создал приспособление:
from betamax import Betamax
@pytest.fixture
def session(request):
session = requests.Session()
recorder = Betamax(session)
recorder.use_cassette(os.path.join(os.path.dirname(__file__), 'fixtures', request.function.__name__)
recorder.start()
request.addfinalizer(recorder.stop)
return session
Итак, теперь в моих тестах я просто использую приспособление session
, и каждый запрос, который я делаю, автоматически сериализуется в файл fixtures/test_name.json
, поэтому в следующий раз, когда я выполняю тест вместо того, чтобы делать реальную библиотеку запросов HTTP, он загружает его из файловая система:
def test_if_response_is_ok(session):
r = session.get("http://google.com")
Это очень удобно, потому что для того, чтобы обновлять эти светильники, мне просто нужно очистить папку fixtures
и повторить мои тесты.