python

Schemathesis: property-based тестирование для API схем

  • воскресенье, 1 декабря 2019 г. в 00:30:58
https://habr.com/ru/post/478114/
  • Python
  • Тестирование веб-сервисов


image


Фото Chris Keats на Unsplash


Многие компании, и мы в том числе, перешли от монолитов к микросервисам ради лучшей масштабируемости и ускорения циклов разработки. У нас всё еще есть монолитные проекты, но они постепенно заменяются набором небольших и аккуратных микросервисов.


Эти микросервисы используют Open API 3.0 схемы для описания того что от них можно ожидать. Схемы дают множество полезных вещей, например автогенерируемые клиенты или интерактивная документация, но их основное достоинство состоит в том, что они помогают контролировать как сервисы общаются между собой.


Межсервисная коммуникация становится более сложной когда количество участников растет и в этой статье, я хочу поделиться своими мыслями о проблемах использования схем в веб приложениях и обозначить некоторые способы как с ними можно бороться.




Даже учитывая что Open API 3.0 во многом превосходит своего предшественника, (так же известного как Swagger 2.0) у него, так же как и у других спецификаций есть множество ограничений. Основная проблема заключается в том, что даже если и описанная схема полностью отражает видение автора, это не значит что реальное приложение будет вести себя согласно схеме.


Существует множество различных подходов для синхронизации схем с документацией и логикой приложения. Наиболее распространенные:


  • Развивать отдельно, синхронизировать вручную;
  • Генерировать схему из приложения (например, при помощи, apispec);
  • Предоставлять логику на основе схемы (connexion);

Ни один из этих подходов не гарантирует 1:1 соответствия поведения приложения и его схеме и на это есть множество причин. Это может быть сложное ограничение на уровне базы данных, которое нельзя выразить на языке схемы или вездесущий человеческий фактор — или мы забыли обновить приложение, чтобы отобразить изменения схемы или наоборот.


Существует множество последствий этих несоответствий, от необработанной ошибки, которая ломает приложение, до проблем с безопасностью, которые могут повлечь серьезные финансовые потери.




Очевидный способ решать эти проблемы это тестировать приложения и настраивать линтеры для схем (такие как Zally от Zalando), что мы и делаем, но ситуация становится сложнее когда вам необходим работать с сотнями сервисов различных размеров.


Классические, example-based тесты имеют некоторую стоимость поддержки и занимает время для написания, но они всё еще являются неотъемлемой частью любого современного процесса разработки. Мы искали дешевый и эффективный способ находить дефекты в наших приложениях, что-то что позволит нам тестировать приложения написанные на разных языках, будет иметь минимальную стоимость поддержки и будет простым в использовании.


Поэтому мы решили исследовать применимость property-based тестирования (PBT) для Open API схем. Сам концепт не нов, впервые его реализовали в Haskell библиотеке QuickCheck Koen Claessen и John Hughes в 1999 году. В наши дни PBT инструменты существуют в большинстве языков программирования, включая Python, наш основной язык для бэкенда. В примерах ниже, я буду использовать Hypothesis за авторством David R. MacIver.


Суть подхода заключается в определении свойств, которые код должен удовлетворять и проверки, что эти свойства выполняются на большом количестве случайно сгенерированных входных данных. Давайте представим простую функцию, которая принимает на вход два числа и возвращает их сумму, а также тест для этой функции. Для примера мы можем ожидать, что наша реализация обладает свойством коммутативности.