Как организовать тестирование, чтобы ускорить и стабилизировать релизы продукта. Часть 1

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

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



    В Дирекции больших данных X5 Retail Group сегодня ведется развитие 13 продуктов, из них 4 – в департаменте монетизации, где продукты ориентированы на внешний рынок, и любая ошибка, будь то дефект на проде или запоздало выпущенная фича, имеет экономический эффект и ведет к потере клиентов. По сути, это внутренние команды, которые зарабатывают на внешнем рынке и играют по правилам малого бизнеса в рамках большой компании.

    Все наши продукты значительно различаются по своим целям и потому требуют разных подходов к разработке и тестированию, но у них много и общего: они пользуются одной инфраструктурой (Kubernetes, Greenplum, тестовые серверы), а разработчики из разных продуктовых команд иногда подменяют друг друга на время отпусков.

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

    Например, два продукта пользуются одной инфраструктурой нагрузочного тестирования, и обоим срочно нужно провести тесты. Не оповещая друг друга, они делают это одновременно, в итоге получают ложные результаты, потому что СУБД «легла», а из-за кого – непонятно. Хотели сэкономить время на переговорах, в итоге потеряли массу времени без всякого результата.
    Не исключены и потери данных. Допустим, один из продуктов занимает свободный тестовый сервер, никого об этом не предупреждая. Официально «железо» считается свободным, поэтому туда заходит другой продукт и случайно стирает все тестовые данные первого. Это, конечно, не пользовательские данные, а всего лишь тестовые, но все равно довольно неприятный кейс.

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

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

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

    Два этих фактора – совместная работа на одной территории и уникальные особенности продуктов – и поставили перед нами задачу: выработать правила, которые позволят командам не мешать друг другу, но при этом не будут связывать тестировщиков и разработчиков по рукам и ногам и не сведут разработку разных продуктов к одному шаблону, зарубив все преимущества agile и продуктового подхода на корню.

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

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

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

    Какие процессы менялись в нашем продукте


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

    Важно заметить, что перемены – это общее дело. Кто бы ни был их инициатором, тестировщик или сами разработчики, без согласия всей команды и сильных союзников не обойтись. Любые изменения нужно обсуждать всей командой, чтобы собрать как можно больше идей и не упустить возможные риски. Деливери и продакт-менеджер нашего продукта и до меня системно работали над улучшением процессов как с технической, так и с продуктовой стороны. Я, придя в команду, рассмотрела процесс со стороны тестирования, и вместе мы продумали согласованную «стратегию перемен». Первым пунктом в ней стало изменение в выкладке кода.

    Порядок выкладки кода


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

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

    Проще всего было бы разделить процесс на две ветки с «чистым» и «грязным» кодом. Но нам нужно было соблюсти множество условий:

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

    Мы потратили 2 часа на обсуждение новой схемы работы и пришли к следующему: заводим три ветки, две из них (release и master) будут с чистым кодом. В «мастере» лежит текущая продуктовая версия, в «релизе» – фичи, готовые к выкатке. В Dev происходит тестирование, тут располагаются задачи, готовые к тесту, разработка проходит локально. Выкатка на каждую ветку происходит по согласованию с тестировщиком. Вот так:



    Что нам это дало в плане тестирования:

    • Время на тестирование каждой задачи по отдельности сократилось на 20%. Больше не требовалось начинать проверку заново, если на тест выкатилась новая задача без предупреждения, новые задачи не блокировали проверку уже сделанных, ускорилось время локализации дефектов.
    • К планируемому дню фиксации релиза непроверенными оставались 1-2 задачи вместо 4 (то есть время на их проверку сократилось вдвое).
    • Сократилось время интеграционного тестирования и тестирования релиз-кандидата с 6 часов до 2 (считая ретест).
    • Снизилось количество дефектов, находимых на этапе релиза. Раньше на первой релизной версии мы находили их более 10, а теперь не более 4. Время на ретест снизилось на 2 часа.
    • Появилась возможность продолжать разработку параллельно с тестированием.

    Общее время, которое мы тратили на тестирование, задерживая выкатку на прод, сократилось на 8 часов. Всего 2 часа обсуждения новой схемы работы с командой – и удалось сберечь целый рабочий день, который раньше приходилось тратить каждые две недели. Неплохо?

    Но и проблемы остались.

    • Разработчики тратили время на оповещение тестировщика о готовности задачи, отвлекались и теряли контекст задачи при необходимости выкатки на тест.
    • На релиз-кандидате продолжали появляться ошибки, связанные с неодинаковой выкаткой на тест, релиз и прод.
    • Хотфиксы на проде при таком подходе были возможны только сразу после выкатки.
    • Не было понимания, когда и где проводить нагрузочное тестирование.

    Итог: мы продолжали задерживаться на работе в день релиза.

    Мы собрались снова. Часть проблем решилась уточнением процесса разработки и добавлением CI:



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

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

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

    Планирование для разработки и тестирования


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

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

    Теперь мы проговариваем все возможные ошибки до начала разработки. Потребовалось стать занудным отличником, который на этапе планирования спрашивает обо всем и вся: «А что будет, если сторонний сервис отвалится?», «А если нам вернется null, а не 0?», «А что если нам придут не все данные?», «А если печенеги нападут?» и так далее, но зато теперь мы были готовы ко всему.

    Также мы начали проговаривать, как именно будем реализовывать ту или иную задачу и как будем ее тестировать. Это позволило сократить самодеятельность (изобретение всяких велосипедов, например) и дало каждому участнику команды понимание, что делают его коллеги. Это, к слову, позволило нам отказаться от критериев приемки (AC).

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

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

    • Формат постановки и приемки задач и дефектов: ушли от user stories к более удобному для нас гибриду “use case + техзадача”.
    • Момент тестирования: установили в релизном цикле 5 точек, в которых тестировщики активно контролируют процесс создания продукта.
    • Правила взаимодействия связки «бэкенд – тестирование – фронтенд»: выработали схему, которая позволила проверять все данные, которые передаются между бэкендом и фронтендом.
    • Ускорение работы по исправлению дефектов: установили правила, как приоритизировать задачи по отладке, чтобы не отвлекать разработчиков лишний раз.

    Эти меры позволили нам сократить релизный цикл с 2,5 недель до 1. Прирост по скорости может показаться небольшим, но главное достижение было в том, что наши релизы стали более стабильными и предсказуемыми – мы получили возможность выкатывать релизы «по команде»: можем собраться в любой день, выкатить задачи и к вечеру все будет готово и отлажено.
    X5 Retail Group
    Все о цифровой трансформации ритейла

    Комментарии 7

      0
      Глядя на стены помещения на КДПВ у меня возник вопрос — почему люди на рабочих местах без касок? И становится понятным почему некоторые из рабочих мест пустые.
        0
        Чувак сидит в шапке в помещении. Это странно, с какой стороны не посмотреть.
          0
          Интересный кейс, спасибо.
          Правда вторая диаграмма не показывает, где же там тестирование?
            0
            Действительно не показывает) вторая диаграмма с ветками и организацией процесса разработки так, чтобы минимизировать необходимость ретеста. К каждой ветке прикреплён свой стейдж. С аналогичным названием) На каждом стейдже происходит свой вариант тестирования.
            0

            Тестирование задачи проходит на всех трёх ветках?

              0
              Да. На дев итерационное, на релизе интеграционное и нагрузочное, на мастере приемочное
              0
              Извините за занудство, но кажется вы изобрели git-flow опять :)
              nvie.com/posts/a-successful-git-branching-model

              Но и проблемы остались.
              — Разработчики тратили время на оповещение тестировщика о готовности задачи, отвлекались и теряли контекст задачи при необходимости выкатки на тест.


              Это легко решается:
              1. статус в jira разраб после in-progres (ну или после review) переводит в статус ready-for-test
              2. вам нужны динамические тест окружения — это когда задача FEATURE-123 автоматически выливается на хост feature-123.your.domian.com — и тестировщик тестит ее — все баги виливаются тудаже — делается автоматически без участия разраба или тестировщика (ну или одной кнопкой в CI) — по хуку в task-менеджере, при переходе в статус ready-for-test

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое