И снова спасибо за подробный ответ! Мы только начинаем писать апи тесты на проекте, хочется на берегу выработать какой-то подход, который в дальнейшем позволит поддерживать тесты без лишней боли. Возможно через годик-другой смогу дать свой фидбек =)
Спасибо за подробный ответ! Я наверное как то криво описывал модель в pydantic, для атрибутов пробовал указывать так же как и вы в пункте 1, но схема генерилась иначе... Ну да ладно. Я правильно понимаю, что вы выстраиваете свой тестовый фреймворк похожим образом? Очень интересно узнать сколько у вас API тестов и как тяжело их поддерживать. Закрадываются мысли вроде "а не проще ли забить на эти модели и оперировать в тестах json'ом, полученным из экземпляра Response". Валидацию схемы же оставить на jsonschema, саму схему генерить на любом удобном сайте по имеющемуся ответу и складывать в одну папочку в репе. Вроде так проще и быстрее, даже коллеги не жалуются на ревью. Поэтому и спрашиваю, быть может вы научены горьким опытом и эмпирически пришли к "паттерну", описанному в статье? Наверняка вы сначала писали тесты иначе, потом столкнулись с какой-то проблемой, которую решили описанным выше образом. Что это была за проблема?
Спасибо за статью, открыл для себя много нового. Постарался написать пару тестов на рабочем проекте следуя описанному выше подходу, хочу поделиться впечатлениями и уточнить пару вещей. 1) Схему удобнее валидировать пытаясь переложить ответ в ожидаемую модель например методом Модель.parse_obj(ответ). Если же использовать способ из статьи, то регулярно будут ошибки для полей, у которых допустимы несколько типов. Может я чего-то не понимаю, но полученная из модели схема всегда содержит в себе только один тип для каждого поля. 2) У нас порядка 40+ микросервисов, у каждого десяток-другой эндпоинтов, соответственно схем будет довольно много, не особо понимаю как это добро структурировать. Сервис 1 вполне вероятно внутри своего ответа использует модель сервиса 2, значит надо либо импортировать эту модель, либо описывать ее заново. В первом случае надо вспомнить что такая модель уже где то описана, что довольно сложно учитывая их общее количество. Во втором случае есть риск накопипастить кучу дублирующего кода. Не понимаю как лучше поступить, интересно послушать про "боевой" опыт поддержки моделей. 3) При реализации HTTP методов (для работы с questions) в аргументах указана ожидаемая модель из которой будет формироваться тело запроса, это круто. Но как получить ожидаемую модель тела ответа? Опять же, при большом количестве моделей легко запутаться. Как будто бы напрашивается еще один слой, переделывающий Response в конкретную модель. Что-то похожее сделано в методе create_question (который из работы с questions). Однако если мы получим ошибку в ответе (а значит другую структуру ответа), то метод упадет и в отчете это будет не особо читаемо. Получается какой-то промежуточный слой между драйвером и тестовой логикой, не понятно нужен ли он вообще и где его реализовать, если он нужен. Возможно эту проблему закрывает QjestionDict. В статье 5 тестов, в 4 из них словарь с ответом аннотируется типом QjestionDict. Это удобно, когда все ручки выдают один ответ, но что делать, когда у каждой ручки своя схема?
С pydantic'ом познакомился недавно, поэтому возможно я просто что-то не понимаю. Буду рад ответам на вопросы.
И снова спасибо за подробный ответ!
Мы только начинаем писать апи тесты на проекте, хочется на берегу выработать какой-то подход, который в дальнейшем позволит поддерживать тесты без лишней боли. Возможно через годик-другой смогу дать свой фидбек =)
Спасибо за подробный ответ!
Я наверное как то криво описывал модель в pydantic, для атрибутов пробовал указывать так же как и вы в пункте 1, но схема генерилась иначе... Ну да ладно.
Я правильно понимаю, что вы выстраиваете свой тестовый фреймворк похожим образом?
Очень интересно узнать сколько у вас API тестов и как тяжело их поддерживать. Закрадываются мысли вроде "а не проще ли забить на эти модели и оперировать в тестах json'ом, полученным из экземпляра Response".
Валидацию схемы же оставить на jsonschema, саму схему генерить на любом удобном сайте по имеющемуся ответу и складывать в одну папочку в репе. Вроде так проще и быстрее, даже коллеги не жалуются на ревью. Поэтому и спрашиваю, быть может вы научены горьким опытом и эмпирически пришли к "паттерну", описанному в статье? Наверняка вы сначала писали тесты иначе, потом столкнулись с какой-то проблемой, которую решили описанным выше образом. Что это была за проблема?
Спасибо за статью, открыл для себя много нового. Постарался написать пару тестов на рабочем проекте следуя описанному выше подходу, хочу поделиться впечатлениями и уточнить пару вещей.
1) Схему удобнее валидировать пытаясь переложить ответ в ожидаемую модель например методом Модель.parse_obj(ответ). Если же использовать способ из статьи, то регулярно будут ошибки для полей, у которых допустимы несколько типов. Может я чего-то не понимаю, но полученная из модели схема всегда содержит в себе только один тип для каждого поля.
2) У нас порядка 40+ микросервисов, у каждого десяток-другой эндпоинтов, соответственно схем будет довольно много, не особо понимаю как это добро структурировать. Сервис 1 вполне вероятно внутри своего ответа использует модель сервиса 2, значит надо либо импортировать эту модель, либо описывать ее заново. В первом случае надо вспомнить что такая модель уже где то описана, что довольно сложно учитывая их общее количество. Во втором случае есть риск накопипастить кучу дублирующего кода. Не понимаю как лучше поступить, интересно послушать про "боевой" опыт поддержки моделей.
3) При реализации HTTP методов (для работы с questions) в аргументах указана ожидаемая модель из которой будет формироваться тело запроса, это круто. Но как получить ожидаемую модель тела ответа? Опять же, при большом количестве моделей легко запутаться. Как будто бы напрашивается еще один слой, переделывающий Response в конкретную модель. Что-то похожее сделано в методе create_question (который из работы с questions). Однако если мы получим ошибку в ответе (а значит другую структуру ответа), то метод упадет и в отчете это будет не особо читаемо. Получается какой-то промежуточный слой между драйвером и тестовой логикой, не понятно нужен ли он вообще и где его реализовать, если он нужен.
Возможно эту проблему закрывает QjestionDict. В статье 5 тестов, в 4 из них словарь с ответом аннотируется типом QjestionDict. Это удобно, когда все ручки выдают один ответ, но что делать, когда у каждой ручки своя схема?
С pydantic'ом познакомился недавно, поэтому возможно я просто что-то не понимаю. Буду рад ответам на вопросы.