Несколько лет назад в Ozon между двумя релизами приложения на одной платформе могло пройти три месяца. Мы планировали, что хотим выпуститься с определенной большой фичей и пока её не сделаем — не релизим.
С чем мы столкнулись, пока выпускали релизы по этой схеме:
Сложно спрогнозировать, когда выйдет фича. Ок, мы как-то прикидывали сроки, но чем больше была разрабатываемая функциональность, тем сложнее точно оценить срок. Трекать прогресс фичи тоже не очень удобно, потому что «оно там делается», и промежуточные билды с чем-то готовым «для посмотреть» сложно собирать.
Долго править баги. В коде они могут быть исправлены быстро. А вот до пользователей фикс доходит уже вместе с той самой глобальной фичей.
Больно отключать легаси. Надо дождаться, когда количество пользователей на новых версиях будет уже достаточно большим. При редких обновлениях ждать этого иногда приходится годами.
Долго релизить мелкие фичи. Какие-то улучшения могут занимать немного времени на разработку, но быть важными для пользователей и бизнеса. Точно так же, как исправления багов в пункте выше, для релиза они будут ждать того «монстра», которого мы пилим три месяца.
Невыносимо долго проводить регрессионное тестирование. Всё, что было переделано за несколько месяцев, мы будем проверять, чинить, перепроверять, чинить, перепроверять… Ну, вы поняли…
Много хотфиксов. Чем больше число и объем изменений, тем сложнее будет найти все баги перед релизом. Вот и появляются хотфиксы. Ещё за такой долгий срок разработки может прилететь какая-то очень срочная фича, ждать нельзя – надо срочно выпускать(например, поддержать разрешение на отслеживание или добавить что-то по срочному рекламному контракту).
Проблем много, и они все значимые. Когда «бизнес» пришёл к нам и сказал, что надо релизить быстрее – мы уже ожидали этого. Но не ожидали, что они скажут: «Релизьте раз в… неделю».
Тут у нас случилась стадия отрицания:«Мы не успеем всё проверить, никаких фичей в релиз не попадет, Apple ревьюит о-го-го сколько. Зачем, почему, может, не надо?». В ответ мы услышали: “Релизы раз в неделю”.
Сокращаем время выпуска релиза: первая попытка
Решили, что надо двигаться к цели итерационно.
Сначала научиться выпускать релиз хотя бы к определённой дате. Первой попыткой был план успеть зарелизить за месяц. Условно, мы решили 1 мая, что следующий релиз должен выйти 1 июня.
Ок, дата есть. Прикинули, что неделя уходит на регресс. На разработку остается три недели. Запланировали работы на весь срок девелопмента.
Параллельно решили начать писать автотесты. Ну, как начать. У нас и до этого они были, но пользы не ощущалось. Поняли, что пора их встраивать в процессы.
Идёт первый месяц. Работаем. Пилим фичи, тестируем. Все заряжены. Но в итоге получили: тот объём работ, который запланировали разработать за три недели, закончили под конец четвёртой. Стали искать, где же выиграть время, нашли только один вариант — тестирование. Как могли, сократили регресс, но всё равно нашли несколько критичных багов. В итоге в зависимости от платформы с релизом опоздали на неделю-полторы.
Вторая попытка: нужно что-то менять
Да, мы решили, что нужны изменения. Но поменяли не процессы, а... сроки. Раз тяжело планировать на месяц – давайте запланируем релиз через две недели! Меньше успеем сделать фичей, быстрее проведем регрессионное тестирование - проще будет запланировать объем работ.
Тем временем тестировщики продолжают писать автотесты…
Пробуем – всё равно каждый раз не успеваем.
Стали анализировать, из-за чего не выходит уложиться в срок:
Неправильно оцениваем время на разработку.
Блочимся бекендом – от этого тормозится и разработка, и тестирование.
Продакты поздно вносят «последние» правки в ТЗ.
Не учитываем время на починку багов.
У нас был план: то, что не готово к началу тестирования – в релиз не идёт. Но он не сработал. Приходили продакты и говорили, что две недели ждать следующего релиза они не могут. Потом уходили «выше», и оттуда нам говорили, что, да, надо доделать.
И тут пришли QA. Сказали, что при двухнедельных релизах скоуп не особо сократился.
Разработчиков много, они разделены по разным функциональностям и за две недели успевают накомитить практически во все компоненты. Стало понятно, что несмотря на то, что мы НИ РАЗУ не успели в срок ни при месячном релизе, ни при двухнедельных – пора двигаться дальше.
Недельные релизы – мы идём к вам!
Прежде всего надо было составить календарь наших действий на неделю. По разработке получилось так:
Понедельник | Релизная ветка |
Вторник | Фичи |
Среда | Фичи |
Четверг | Фичи |
Пятница | Фиксы багов |
Фичи уходят в свои «фича-ветки». И когда она полностью сделана, проверена, принята продактом, тогда уже попадает в develop. И вот на протяжении недели готовые фичи собираются в dev, в пятницу правим баги уже напрямую там. А в понедельник всё, что собралось – отрезается в отдельную релизную ветку. В релиз уже ничего не коммитим, только фиксим баги, найденные на релизном тестировании. Получается, что где-то в среду-четверг должен начаться процентный роллаут приложения. |
Меняемся в тестировании
Чтобы всё это поддержать со стороны QA, пришлось ротировать обязанности тестировщиков по неделям. Одну неделю тестер проверяет фичи, вторую – занимается написанием кейсов и автотестов, участвует в релизном тестировании. При этом релизное тестирование получилось сократить где-то до дня на каждую платформу.
Помогли в этом наконец-то дописанные автотесты, которые регрессили большую часть приложения и сокращенный скоуп - в ручном релизном тестировании участвовали только кейсы смоука и функциональность, которая была задета в фичах этого релиза.
Чтобы разработка не зависала на начальных этапах, мы выработали требования к фиче, которую берём в работу – у неё должны быть в наличии
Дизайн;
Бекенд;
Контракт.
Если чего-то из этого нет – смысла брать фичу в разработку на мобильной платформе тоже нет.
Дальше встал вопрос о том, когда же можно включать фичу в релиз. Получились такие правила:
Бекенд фичи должен быть на продакшене.
К началу релизного тестирования нет критичных багов(ни на фронте, ни на бекенде).
Для фичи есть фичефлаг, которым в любой момент можно закрыть функциональность. По версии платформы, по версии приложения, по дате, на определенную группу пользователей – как угодно.
Меняемся в разработке
В разработке тоже много чего поменяли. Прежде всего, появился максимальный приоритет на переоткрытых тикетах. Потому что нам неважно, как много мы сделаем, если ничего из этого не попадет в релиз. Важно именно закрыть тикет, чтобы в итоге фича попала в dev.
Ещё мы постоянно автоматизируем процессы, чтобы разработчикам надо было меньше отвлекаться на какие-то рутинные вещи, и они могли сконцентрироваться на разработке.
Тикет автоматом двигается по статусам. Запушил коммит – перешел в in progress. Создал merge request – перешел в code review. Прошел review – попал в QA.
В тикете автоматически проставляется версия релиза, куда он попал и номер билда.
По каждой сборке запускаются UI- автотесты по затронутой функциональности. Это тоже определяется «само» по измененным файлам в merge request. В результате репорт попадает в комментарий тикета в Jira.
Даже merge request на влитие эпика в dev создаётся просто по принятию продактом фичи в Jira. Если нет конфликтов, то и вливается сам. Релиз сам закрывается, а новый сам создаётся.
QA Notes
Ещё мы ввели требования к разработчикам писать QA Notes. Там указывается:
Что было сделано.
Что могло быть задето.
Приложены скриншоты или видео.
На какой среде удалось проверить.
Для бага — ещё причина, из-за чего сломалось (в идеале тикет, который привёл к такому поведению).
QA Notes позволили значительно ускорить тестирование и ревью кода. А ещё дали нам скрытый бонус: пропали реопены от QA из-за крешей на старте.
Тестировщикам пришлось тоже много чего поменять в своих процессах. Раньше любой человек из QA мог взять тикет на тестирование любой части приложения. По задумке, это давало больше вовлечённости и свежих взглядов. Но тормозило тестирование. Теперь тестировщики разделены по функциональностям и чаще проверяют то, что за ними закреплено. Получается быстрее.
Автотесты раньше находят баги. Теперь не надо ждать релизного тестирования, чтобы увидеть проблемы после интеграции. Прогоны автотестов происходят после каждого вливания эпика в dev, а также каждую ночь. Если надо, то можно запустить на эпик-ветке до вливания в dev. Раньше нашли баг – раньше исправили.
Как и у разработчиков, у QA появился приоритет на функциональности, которая попадает в релиз. Именно эти тикеты важнее всего проверять в первую очередь.
А еще добавилась ротируемая роль «QA за релиз». Этот тестировщик где-то раз в два–три месяца делает повторяющиеся вещи:
Составляет набор релизных тестов.
Распределяет нагрузку команды тестирования по фичам. Если видит, что у одних сейчас мало тикетов, а другие не успевают – может перекинуть кого-то в помощь.
Напоминает тестировщикам посмотреть отчёты по автотестам на релизном билде.
Пушит пересборку релиз-кандидатов, если что-то добавилось.
После релиза неделю мониторит падения и отвечает на запросы поддержки.
В автоматизацию тестирования мы добавили не только проверки функциональности, но и аналитику, отправляемую приложением.
Автоматизация помогает контролировать стабильность среды с помощью выполнения тестов после изменения кода приложения:
Мы также проверяем, что новые автотесты не ломают существующие:
Новая схема релиза мобильных приложений
У нас стало значительно меньше хотфиксов. Релизы теперь чаще в пять-десять раз, но хотфиксим мы реже, чем раньше. Причины две. Во-первых, получается делать более стабильные релизы. Во-вторых, если это не что-то невероятно критичное, то фикс, скорее всего, сможет подождать неделю до следующего релиза.
Теперь мы спокойнее переносим фичи. Неприятно, когда не успели, но перенос выхода фичи на неделю воспринимается спокойнее, чем на более долгий срок.
Продактам стало проще проверять готовность. Раньше они приходили к концу разработки, которая длилась месяц-другой, а теперь каждую неделю видят, что происходит(а хорошие продакты – чаще :) ).
И главное. Мы теперь укладываемся в сроки. Всегда. С первой попытки выпустить релиз за неделю – мы успели это сделать. И с тех пор вот уже два года приложение Ozon обновляется раз в неделю, принося новые фичи, исправления ошибок.
Какие есть сложности
В первую очередь это непростой рефакторинг. Когда вмержив один коммит, вам надо перепроверить всё приложение. Сейчас мы прежде всего вливаем такое по понедельникам-вторникам, чтобы рефакторинг максимально «настоялся» в dev, накрутился автотестами и был потроган при тестировании фичей.
Ещё одна сложность – праздники, из-за которых рабочая неделя из пяти дней сокращается до четырёх. Тут появляется больше риска, т.к. обычно мы релизим на третий-четвёртый день после отрезания релизной ветки и остаётся ещё день на мониторинг. Тогда как здесь обычно релиз происходит уже в последний рабочий день. Спасибо, фичефлагам и процентной раскатке.
Что ещё можно улучшить
Прежде всего хочется научиться ещё раньше раскатывать билды на пользователей. Найти тестовые сегменты, на которые можно катить до начала релизного тестирования. Но это риск имиджевых и денежных потерь. Таких суперлояльных пользователей нам ещё только предстоит поискать. Если вдруг вам может быть это интересно – пишите, добавим вас в сегмент бета-тестировщиков.
Ещё мы никогда не останавливаемся в автоматизации процессов. Постоянно находим возможность убрать ручную рутину. И покрываем автотестами всё больше функциональности.
Для себя мы выработали такие шаги, на которые надо пойти, чтобы завести у себя релизы раз в неделю:
Строгие требования к готовности фичи.
Приоритет на переоткрытых тикетах.
Вся функциональность закрыт фичефлагами.
Строгое расписание релизов.
И напоследок хочется сказать, если вы захотите перейти у себя на недельные релизы, будьте готовы, что меняться придется везде: и в разработке, и в тестировании, и в продуктовом планировании.