Тестирование client-api проекта
Здесь я опишу один способ тестирования проекта который состоит из API и клиента. И то и другое является самописным и идет как один проект.
И так что же мы имеем: django, django-piston, tddspry.
С тестированием отдельно взятого API проблем как и полагается - нет. А вот с клиентом - есть. Можно конечно запускать сервер API и при тестировании клиента дергать его, но тогда не будет очищаться база данных. Так же можно для каждого теста перезапускать API-сервер и тогда не будет проблем со сбросом базы. Но оба этих метода не совсем удобны, они значительно увеличивают время прохождения тестов. А так же дергать API по сети, пусть даже это и loopback, тоже добавляет времени на выполнение.
Так как у нас для вызова методов API есть отдельная функция, было решено написать такую же функцию только которая делает прямой вызов метода без никакой сети.
Стопором в данной ситуации стало формирование request’а который нужно передавать в view. Это должен быть либо WSGIRequest
либо ModPythonRequest
. Я использовал WSGIRequest
.
if body: # словарь POST/PUT запроса
for key, item in body.items():
body[key] = smart_str(item, 'utf-8') # решение первых граблей, подсмотреное в коде django
query = urllib.urlencode(body or '')
request = WSGIRequest({
'SERVER_NAME': 'test_api',
'SERVER_PORT': '8000',
'REQUEST_METHOD': method,
'CONTENT_TYPE': 'application/x-www-form-urlencoded',
'CONTENT_LENGTH': len(query),
'SERVER_NAME': 'localhost',
'SERVER_PORT': 8088,
'wsgi.input': StringIO(query), # решение вторых граблей
})
Список граблей:
- параметры запрос это ansi срока,
urllib.urlencode
не умеет работать с юникодом - тело запроса передается внутри файлового объекта
А дальше все хорошо
Что бы получить функцию обрабатывающую url, нужно импортировать urlpatterns
из urls.py
и пройтись по этому массиву вызывая resolve
пока не найдет обработчик.
Если вы используете django-piston и хендлеры у вас с аутентификацией, то создайте ресурс заново уже без аутентификации.
P.S.: здесь не учитывается возможность передавать файлы