- PVSM.RU - https://www.pvsm.ru -
Добрый день уважаемые жители !
Работая на текущем проекте, я столкнулся с проблемой однотипных данных и необходимостью протестировать разные http вызовы над одними и теми же данными.
Проект разрабатывается на django/django-rest-framework/python3.5.
Поначалу я начал использовать этот движок для упрощения тестирования django-rest-framework (django-rest-assured — https://github.com/ydaniv/django-rest-assured [1]).
Но, имея необходимость протестировать по сути одни и те же данные на разных урлах, я осознал, что использование этого движка не помогло так уж сильно облегчить задачу.
Конечно, в какой то мере проект стал более податливым для тестирования. Но, возникало много вопросов с так называемыми django-rest-framework detail_route и list_route. Тем, кто не в курсе напомню, эти декораторы позволяют определить специфические действия выполняющиеся над каким то конкретным типом данных (дальше, ресурсом).
И потом я понял, что тесты в проекте нужно группировать относительно ресурсов (типов) данных, над которыми они тестируются.
К примеру, возьмем объект машина, стоит цель продать машину, какие действия могут быть выполнены над ней и какие типы запросов могут быть в отношении этого объекта (машина):
Это все будет одна машина, одна запись из базы данных.
Но разные http запросы. Я согласен, что может быть не совсем удачный пример с машиной, ибо http запросами не оценить стоимость восстановления машины… Да и понятно же что много из этих данных могут быть возвращены при GET запросе касательно этой машины (и дополнительные http запросы могут не потребоваться), но предположим это не так. И тут возникает проблема: у нас одна машина, но куча тестов для каждой из операций над этой машиной. Почему бы не сгруппировать все эти тесты в один набор тестов но над одним ресурсом.
Я приведу пример xml, который можно было бы написать для набора таких тестов:
<resource id="normal_car">
<rest url="/api/core/cars/{id}/is_fine/" method="get" />
<rest url="/api/core/cars/{id}/repair_cost_and_time/" method="get" />
<rest url="/api/core/cars/{id}/is_available/" method="get" />
<rest url="/api/core/cars/{id}/bet/" method="post" />
</resource>
Сразу замечу, почему я здесь привожу ссылку с {id}, я использую в easytest движке open api схему для генерации фикстур для запроса и тд и тп.
И в openapi схеме ссылка для detail запросов связанных с конкретных ресурсом генерируются как:
"/api/core/cars/{id}/bet/": {
"post”: {
"consumes": [
"application/json"
],
"description": "Description",
"operationId": "operationId",
"parameters": [
{
"description": "",
"in": "path",
"name": "id",
"required": true,
"type": "string"
},
{
"in": "body",
"name": "data",
"schema": {
"properties": {
"price": {
"description": "",
"type": "integer"
},
},
"required": [
"price"
],
"type": "object"
}
}
],
}
}
Затем, имея open api схему, мы можем:
Именно для этого я сделал easytest движок.
Во первых, никакого кода для тестов не генерируется. Зачем нам код для тестов если схема для тестов описана уже в open api схеме? Единственное что нам нужно – это возможность определять кастомные setup, teardown, matcherы для http вызовов, и это все что нам нужно иметь возможность делать для осуществления тестирования. Кстати, нужно еще не забывать что разные http вызовы могут требовать разного режима базы данных, некоторые — READ_UNCOMMITED, некоторые — READ COMMITED. Это тоже учтено в движке.
Теперь по порядку о том как все работает:
Однако, вы должны определить один тест, в котором вы сделаете инициализацию easytest и напишете что то подобное:
кликните, чтобы перейти на пример теста для django + drf [8]
На сегодняшний момент, в случае падения теста происходит вывод того что упало, на каком эндпоинте, и traceback exceptionа в консоль (терминал) в красном цвете. И если хоть один тест упал, то падает весь тест test_resources с следующим сообщением:
Automatic test of endpoints has been failed
Пока еще не опубликовал пакет на pypi. Еще думаю над названием, но уже использую в своем проекте, в котором порядка 100 эндпоинтов. Сильно облегчает жизнь
Из недостатков:
Автор: незнакомец
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/260603
Ссылки в тексте:
[1] https://github.com/ydaniv/django-rest-assured: https://github.com/ydaniv/django-rest-assured
[2] bitbucket xml: https://bitbucket.org/sergeyglazyrindev/python-easytest/src/5428bcf5f209913b5d6ee799dee029de441c6b46/tests/django/project/easytest.xml?at=master&fileviewer=file-view-default
[3] ссылка на dtd файл: https://bitbucket.org/sergeyglazyrindev/python-easytest/src/5428bcf5f209913b5d6ee799dee029de441c6b46/easytest/dtd.xml?at=master&fileviewer=file-view-default
[4] bitbucket drf specific request, test visitor classes: https://bitbucket.org/sergeyglazyrindev/python-easytest/src/5428bcf5f209913b5d6ee799dee029de441c6b46/easytest/drf/request.py?at=master&fileviewer=file-view-default
[5] ссылка на код: https://bitbucket.org/sergeyglazyrindev/python-easytest/src/5428bcf5f209913b5d6ee799dee029de441c6b46/tests/django/project/project/easytest_extended/tests/test_resources.py?at=master&fileviewer=file-view-default#test_resources.py-12:25,40,41
[6] ссылка на код: https://bitbucket.org/sergeyglazyrindev/python-easytest/src/5428bcf5f209913b5d6ee799dee029de441c6b46/tests/django/project/project/easytest_extended/tests/test_resources.py?at=master&fileviewer=file-view-default#test_resources.py-43:51
[7] ссылка на код: https://bitbucket.org/sergeyglazyrindev/python-easytest/src/5428bcf5f209913b5d6ee799dee029de441c6b46/tests/django/project/project/easytest_extended/tests/test_resources.py?at=master&fileviewer=file-view-default#test_resources.py-63:84
[8] кликните, чтобы перейти на пример теста для django + drf: https://bitbucket.org/sergeyglazyrindev/python-easytest/src/5428bcf5f209913b5d6ee799dee029de441c6b46/tests/django/project/project/easytest_extended/tests/test_resources.py?at=master&fileviewer=file-view-default#test_resources.py-91:131
[9] Источник: http://habrahabr.ru/sandbox/110060/
Нажмите здесь для печати.