Привет! Хочу рассказать вам, как устроено тестирование в проекте Автотека, сервисе проверки автомобилей по VIN. Под катом — о том, какие инструменты мы используем для тестирования требований, планирования спринта, как устроен процесс тестирования в нашем проекте.
Мы в Автотеке используем скрам, так как это наиболее удачная методология для наших задач. Еженедельно мы проводим собрания, на которых приоритизируем, определяем сложность, декомпозируем задачи из бэклога и устанавливаем Definition of Ready и Definition of Done для каждой из задач (о них можно прочитать в этой замечательной статье). Этот процесс называется backlog grooming.
Для эффективного груминга необходимо учитывать все зависимости. Знать, каким образом реализация задачи может негативно повлиять на проект. Понимать, какой функционал нужно поддержать, а какой — выпилить. Возможно, в процессе реализации задачи может пострадать API для партнёров, или нужно просто не забыть реализовать метрики, по которым можно понять бизнес-эффективность. С развитием любого проекта подобных зависимостей становится все больше, и учесть их все становится все сложнее. Это плохо: службе поддержки важно вовремя узнавать о всех фичах. А иногда нововведения надо согласовывать с отделом маркетинга.
В результате мною было предложено решение на основе MindMap, где были отражены почти все зависимости, которые могли повлиять на DoD, DoR и оценку задачи.
Преимуществом такого подхода является визуальное представление всех возможных зависимостей в иерархическом стиле, а также дополнительные плюшки в виде иконок, выделения текста и разноцветных веток. Доступ к этому MindMap имеет вся команда, что позволяет поддерживать карту в актуальном состоянии. Болванку такой карты, которую можно взять за ориентир, выкладываю здесь же — пынь. (Оговорюсь сразу, что это только ориентир, и использовать эту карту для ваших задач без доработки под проект — весьма сомнительно.)
В нашем проекте довольно большое количество golang-кода, и для того, чтобы code style соответствовал определенным стандартам, было решено применить статический анализ кода. О том, что это такое, на Хабре есть отличная статья.
Нам хотелось встроить анализатор в процесс CI, чтобы при каждой сборке проекта запускался анализатор, и в зависимости от результатов проверки, билд продолжался или падал с ошибками. В целом использование gometalinter отдельным шагом (Build step) в Teamcity было бы неплохим решением, но просмотр ошибок в логах сборки не так чтобы очень удобен.
Мы продолжили искать и обнаружили Linty Bot, разработанный в рамках хакатона в Авито Артемием Flaker Рябинковым.
Это бот, который следит за кодом проекта в нашей системе контроля версий и при каждом пулл реквесте запускает анализатор кода на diff. Если при анализе произошли ошибки, бот посылает комментарий в этот PR к нужной строке кода. Его преимущества — скорость подключения к проекту, скорость работы, комментарии к пулл реквестам, и использование довольно популярного линтера Gometalinter, который по умолчанию уже содержит все необходимые проверки.
Следующий раздел — относительно стабильности тестов. Автотека крайне зависит от источников данных (они приходят от дилеров, государственных служб, станций технического обслуживания, страховых компаний и других партнеров), но их неработоспособность не может являться основанием для отказа от проведения тестов.
Мы должны проверять сборку отчетов и при работающих источниках, и при их неработоспособности. До недавнего момента мы использовали в dev-окружении реальные источники данных, и, соответственно, были зависимы от их состояния. Получалось, что мы опосредованно проверяли в UI-тестах эти источники. В результате имели нестабильные тесты, которые отваливались вместе с источниками и ожидание опроса источников данных, что не способствовало скорости прохождения автотестов.
У меня была идея написать свой мок и тем самым произвести подмену источников Автотеки. Но в итоге было найдено более простое решение — уже готовый MockServer, open-source разработка на Java.
Принцип его работы:
Пример создания ожидания с помощью java-клиента:
Как видно из примера, мы описываем запрос, который пришлём, и ответ, который хотим получить. MockServer получает запрос, пытается его сравнить с теми, которые были созданы, и если есть совпадения, возвращает ответ. Если запрос не сматчился, получим 404.
Для MockServer существуют клиенты для Java и JavaScript, отличная документация и примеры использования. Есть возможность матчинга запросов по RegExp, подробное логирование на сервере и еще куча всяких фишек. Для наших нужд это был идеальный кандидат. Процесс запуска подробно описан на сайте, поэтому пересказывать его здесь не вижу смысла. Единственный момент, latest версия довольно сильно протекала по памяти, поэтому мы используем версию 5.2.3. Будьте внимательны. Ещё один минус — Mockserver не имеет поддержки SOAP из коробки.
В данный момент MockServer уже работает у нас около трех месяцев. В результате увеличилась стабильность тестов, скорость их выполнения и возможность получать на dev-среде любые данные. А соответственно, появилось больше возможностей для тестирования.
Эти технологии — основное, о чем хотелось бы рассказать в этой статье. В остальном мы используем обычные инструменты для тестирования: API тесты связкой Kotlin+JUnit+RestAssured, Postman для удобства обращения к API. В этой обзорной статье я не рассказал о нашем подходе к UI тестам. Мы используем MBT и graphwalker. Планируем с коллегами подготовить пост об этом.
Если у вас появились какие-либо вопросы, задавайте в комментариях, я постараюсь ответить. Надеюсь эта статья окажется полезной для команд разработки. (Кстати, пока она готовилась к выпуску, у нас в команде появилась вакансия QA developer, покажите тем, кому это может быть интересно).
MindMap’s для груминга задач
Мы в Автотеке используем скрам, так как это наиболее удачная методология для наших задач. Еженедельно мы проводим собрания, на которых приоритизируем, определяем сложность, декомпозируем задачи из бэклога и устанавливаем Definition of Ready и Definition of Done для каждой из задач (о них можно прочитать в этой замечательной статье). Этот процесс называется backlog grooming.
Для эффективного груминга необходимо учитывать все зависимости. Знать, каким образом реализация задачи может негативно повлиять на проект. Понимать, какой функционал нужно поддержать, а какой — выпилить. Возможно, в процессе реализации задачи может пострадать API для партнёров, или нужно просто не забыть реализовать метрики, по которым можно понять бизнес-эффективность. С развитием любого проекта подобных зависимостей становится все больше, и учесть их все становится все сложнее. Это плохо: службе поддержки важно вовремя узнавать о всех фичах. А иногда нововведения надо согласовывать с отделом маркетинга.
В результате мною было предложено решение на основе MindMap, где были отражены почти все зависимости, которые могли повлиять на DoD, DoR и оценку задачи.
Преимуществом такого подхода является визуальное представление всех возможных зависимостей в иерархическом стиле, а также дополнительные плюшки в виде иконок, выделения текста и разноцветных веток. Доступ к этому MindMap имеет вся команда, что позволяет поддерживать карту в актуальном состоянии. Болванку такой карты, которую можно взять за ориентир, выкладываю здесь же — пынь. (Оговорюсь сразу, что это только ориентир, и использовать эту карту для ваших задач без доработки под проект — весьма сомнительно.)
Linty и статический анализ кода для Go
В нашем проекте довольно большое количество golang-кода, и для того, чтобы code style соответствовал определенным стандартам, было решено применить статический анализ кода. О том, что это такое, на Хабре есть отличная статья.
Нам хотелось встроить анализатор в процесс CI, чтобы при каждой сборке проекта запускался анализатор, и в зависимости от результатов проверки, билд продолжался или падал с ошибками. В целом использование gometalinter отдельным шагом (Build step) в Teamcity было бы неплохим решением, но просмотр ошибок в логах сборки не так чтобы очень удобен.
Мы продолжили искать и обнаружили Linty Bot, разработанный в рамках хакатона в Авито Артемием Flaker Рябинковым.
Это бот, который следит за кодом проекта в нашей системе контроля версий и при каждом пулл реквесте запускает анализатор кода на diff. Если при анализе произошли ошибки, бот посылает комментарий в этот PR к нужной строке кода. Его преимущества — скорость подключения к проекту, скорость работы, комментарии к пулл реквестам, и использование довольно популярного линтера Gometalinter, который по умолчанию уже содержит все необходимые проверки.
MockServer и как заставить сервисы отдавать то, что нужно
Следующий раздел — относительно стабильности тестов. Автотека крайне зависит от источников данных (они приходят от дилеров, государственных служб, станций технического обслуживания, страховых компаний и других партнеров), но их неработоспособность не может являться основанием для отказа от проведения тестов.
Мы должны проверять сборку отчетов и при работающих источниках, и при их неработоспособности. До недавнего момента мы использовали в dev-окружении реальные источники данных, и, соответственно, были зависимы от их состояния. Получалось, что мы опосредованно проверяли в UI-тестах эти источники. В результате имели нестабильные тесты, которые отваливались вместе с источниками и ожидание опроса источников данных, что не способствовало скорости прохождения автотестов.
У меня была идея написать свой мок и тем самым произвести подмену источников Автотеки. Но в итоге было найдено более простое решение — уже готовый MockServer, open-source разработка на Java.
Принцип его работы:
- создание ожидания,
- матчинг поступающих запросов,
- если совпадение найдено — отправляем ответ.
Пример создания ожидания с помощью java-клиента:
new MockServerClient("localhost", 1080)
.when(
request()
.withMethod("POST")
.withPath("/login")
.withBody("{username: 'foo', password: 'bar'}")
)
.respond(
response()
.withStatusCode(302)
.withCookie(
"sessionId", "2By8LOhBmaW5nZXJwcmludCIlMDAzMW"
)
.withHeader(
"Location", "https://www.mock-server.com"
)
);
Как видно из примера, мы описываем запрос, который пришлём, и ответ, который хотим получить. MockServer получает запрос, пытается его сравнить с теми, которые были созданы, и если есть совпадения, возвращает ответ. Если запрос не сматчился, получим 404.
Для MockServer существуют клиенты для Java и JavaScript, отличная документация и примеры использования. Есть возможность матчинга запросов по RegExp, подробное логирование на сервере и еще куча всяких фишек. Для наших нужд это был идеальный кандидат. Процесс запуска подробно описан на сайте, поэтому пересказывать его здесь не вижу смысла. Единственный момент, latest версия довольно сильно протекала по памяти, поэтому мы используем версию 5.2.3. Будьте внимательны. Ещё один минус — Mockserver не имеет поддержки SOAP из коробки.
В данный момент MockServer уже работает у нас около трех месяцев. В результате увеличилась стабильность тестов, скорость их выполнения и возможность получать на dev-среде любые данные. А соответственно, появилось больше возможностей для тестирования.
Эпилог
Эти технологии — основное, о чем хотелось бы рассказать в этой статье. В остальном мы используем обычные инструменты для тестирования: API тесты связкой Kotlin+JUnit+RestAssured, Postman для удобства обращения к API. В этой обзорной статье я не рассказал о нашем подходе к UI тестам. Мы используем MBT и graphwalker. Планируем с коллегами подготовить пост об этом.
Если у вас появились какие-либо вопросы, задавайте в комментариях, я постараюсь ответить. Надеюсь эта статья окажется полезной для команд разработки. (Кстати, пока она готовилась к выпуску, у нас в команде появилась вакансия QA developer, покажите тем, кому это может быть интересно).