Как мы контролируем качество разработки мобильных приложений

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

Если вы — команда специалистов, которая разрабатывает топовые цифровые продукты, скорее всего, вы давно относитесь к ошибкам, как к части процесса. Но чем сложнее проект, тем выше цена мелкой ошибки в его фундаменте. Как быть в случае обнаружения проблемы: страдать из-за уязвленного самолюбия или притворяться, что так и было задумано?

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

  • Архитектурный комитет
  • Дизайн-ревью
  • Кодогенерация
  • Линтеры и автоматизированные тесты
  • Стандартизация
Как мы контролируем качество разработки мобильных приложений

Архитектурный комитет

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

В результате проектирования появляется архитектура приложения, которую изучает архитектурный комитет — встреча, на которой оценивают технические решения. А также сопоставляют их с целями бизнеса и проверяют, действительно ли решение для каждой задачи — лучший вариант из возможных. На встрече участники находят узкие места, отказываются от компромиссных решений и подбирают более оптимальные.

Архитектурный комитет проверяет:

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

Как-то раз на архкоме для приложения сети быстрого питания мы нашли ошибку в процессе подтверждения номера телефона. Если бы приложение вышло в релиз и новый пользователь запросил в нем SMS-код, оно бы отправило ему одно из двух сообщений:

  • С кодом — если этот пользователь входил в клиентскую базу.
  • Со словами «Такого пользователя нет» — если его в базе не было.

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

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

Дизайн-ревью

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

Кто участвует в дизайн-ревью и что они делают:

  • Аналитики проверяют, насколько дизайн отвечает целям и требованиям бизнеса и комментируют его реализацию. Вместе с этим они фиксируют мелкие несоответствия и не до конца понятные места в требованиях.
  • Бэкенд-разработчики изучают, как дизайн будет взаимодействовать с бэкендом. Например, какое обращение к бэкенду повлечет переход на тот или иной экран приложения. Помимо этого, они выбирают подходящие способы обработки данных для отображения на экране нужной информации.
  • Фронтенд-разработчики оценивают, как технически реализовать в приложении идеи дизайнеров.

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

Если команда разработки не пропустила этап дизайн-ревью, скорее всего этого никто не заметит: приложение будет просто красивым, логичным и удобным. Зато признаки отсутствия дизайн-ревью заметит даже пользователь, далекий от мобильной разработки.

Мы часто находим их, когда делаем для заказчиков аудит предыдущего приложения. Например, распространенная ошибка — показывать пользователю экран с запросом на отправку уведомлений сразу после запуска. Если человек еще не получил позитивный опыт взаимодействия, у него нет мотивации для согласия. Вместо этого приложению лучше немного подождать, а затем показать запрос и объяснить пользователю, что если он разрешит уведомления, будет получать секретные акционные предложения. Тогда больше пользователей разрешат уведомления, и бизнес останется на связи с большим количеством клиентов.

Кодогенерация

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

Мы предотвращаем их с помощью кодогенерации и принципа «contract first». Для этого нужно описать в формате спецификаций контракты для взаимодействия компонентов: например, OpenAPI для REST API, protobuf для gRPC и других бинарных протоколов. После этого мы генерируем типы данных и компоненты — клиентские и серверные.

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

Линтеры и автоматизированные тесты

Разработчик пишет код и проверяет его линтерами и автотестами сам — до того, как передать тестировщикам. Помимо этого, он встраивает линтер в CI/CD, чтобы проверить код перед слиянием веток или развертыванием на стенды.

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

Также мы проверяем код с помощью модульных и интеграционных тестов. Модульные тесты — юнит-тесты, проверяют ограниченные участки программы, функции и алгоритмы бизнес-логики. Юнит-тестами лучше покрывать исключительно трудные участки. Например, если вы не до конца уверены в куске кода — его можно пропустить через юнит-тесты и либо увеличить уверенность, либо найти и исправить ошибку.

Тем не менее, совершенное покрытие юнит-тестами не гарантирует правильной работы модулей системы в сборе — даже если по отдельности они работали без проблем. Убедиться в этом помогают интеграционные тесты.

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

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

Стандартизация

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

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

Подведем итоги: замечать и исправлять ошибки, пока они маленькие — выгодно, и в этом помогает система контроля качества на каждом этапе проекта. Она бережет время и силы команды, а также бюджет заказчика. В статье мы разобрали и аргументировали инструменты, которые подобрали для себя. Вы можете позаимствовать их, кастомизировать и выстроить собственную систему контроля качества.

55
Начать дискуссию