377
0
1
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
Назад

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

Время чтения 1 минута
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
377
0
1
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники

Привет, меня зовут Николай Николенко, я CTO и сооснователь IT-компании KODE, которая создает цифровые продукты. Расскажу, как мы контролируем качество мобильных приложений на ранних этапах разработки.

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

Какие способы мы используем:

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

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

Разработка мобильного приложения начинается с проектирования системы. Команда продумывает архитектуру и визуализирует ее в HLD-диаграмме. HLD означает high level design — дизайн высокого уровня, который объясняет архитектуру системы. Диаграмма показывает сервисы и микросервисы, компоненты, интеграции и взаимодействие между ними, а также характер передаваемых данных.

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

Комитет оценивает:

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

Например, однажды мы проводили архитектурный комитет, на котором обсуждали разработку приложения для сети заведений быстрого питания. Рассматривая механизмы регистрации и авторизации, дошли до процесса подтверждения номера телефона и обнаружили уязвимость. Когда новый пользователь запрашивал код в СМС, приложение присылало ему один из двух вариантов сообщения. Первое с кодом — если пользователь уже был в клиентской базе. Второе — с текстом «Такого пользователя нет». Эта формулировка прямо указывала, что телефонного номера в клиентской базе нет. Злоумышленники могли бы автоматически прогнать через приложение десятки тысяч номеров, вычислить те, что принадлежат клиентам, и продать их конкурентам. На архитектурном комитете мы обнаружили ошибку и скорректировали процедуру регистрации, чтобы из него нельзя было понять, есть пользователь в базе или нет.

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

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

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

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

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

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

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

Принцип contract first и кодогенерация помогают избежать досадных ошибок из-за рассогласований на стыке фронтенда и бэкенда, а также при межсервисном взаимодействии.

Мы описываем контракты для взаимодействия компонентов в формате спецификаций: для REST API, например, OpenAPI; для gRPC и других бинарных протоколов — protobuf. Затем генерируем типы данных, а также клиентские и серверные компоненты. Таким образом мы исключаем ситуации, когда участники взаимодействия по-разному реализовали типы и компоненты для связи. Ведь даже такие незначительные оплошности затрудняют отладку и поиск ошибок.

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

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

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

Разработчик запускает линтер вручную самостоятельно, пока пишет код. А также встраивает в CI/CD, чтобы проверить перед слиянием веток или развертыванием на стенды.

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

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

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

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

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

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

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

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

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

Комментарии1
Ilya
6 месяцев назад
Вы работаете по Agile?
Тоже интересно
Комментировать
Поделиться
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники