Являются ли разборки и стабильное развитие противоречием?

11

Я являюсь частью группы разработчиков с 5 командами, всего около 40 разработчиков. Мы следуем методологии Scrum с 3-недельными спринтами. У нас есть установка непрерывной интеграции (Jenkins), конвейер сборки которой занимает несколько часов (из-за обширных автоматических тестов). В основном процесс разработки работает хорошо.

Однако мы наблюдаем, что после нескольких дней нового спринта наша сборка часто становится нестабильной и остается шаткой до тех пор, пока конец спринта не завершится. Отрицательный эффект этого состоит в том, что шаги сборки далеко вниз по конвейеру, особенно UI- / Webtests, не выполняются в течение нескольких дней (потому что запускаются только при «зеленой» сборке). Следовательно, вновь появившиеся ошибки часто обнаруживаются только очень поздно в спринте.

  • Каждый коммит проверяется на соответствие базовому набору тестов. После проверки изменение передается мастеру после проверки кода (Gerrit).
  • Базовые юнит-тесты запускаются каждые 30 минут, продолжительность менее 10 минут
  • Интеграционные тесты запускаются каждые 2 часа, продолжительность 1 час
  • UI- / Webtests запускаются на успешных интеграционных тестах, продолжительность нескольких часов

В зависимости от того, кто отвечает за стабильность сборки во время спринта (эта ответственность передается за спринт), могут существовать промежуточные, специальные «фиксации остановки», чтобы вернуть сборку в стабильное состояние.

Итак, мы хотим:

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

Учитывая (2), точки (1) и (3) кажутся противоречащими друг другу. У кого-нибудь есть хорошая практика, как с этим бороться?

( В настоящее время мы ослабляем точку (2) и разрешаем продолжение сборки даже на неудачных этапах сборки. У меня пока нет отзывов о том, как это влияет на наше качество )

Спасибо симон

Саймон
источник
3
Я бы сказал, что если сборка происходит, several hoursто это реальная проблема. это означает, что комбинированное решение слишком большое и слишком широкое. Вы должны попытаться создать компонентное решение и затем иметь небольшие куски кода в виде пакетов (так или иначе доступных на всех основных языках на всех платформах). Таким образом, любые изменения будут распространяться только на компоненты и будут обнаружены намного быстрее. Полная сборка, по сути, просто объединит вместе уже объединенные компоненты, а также будет быстрее. Тогда вы можете запустить только некоторые тесты, чтобы убедиться, что правильные компоненты были разрешены.
Зайцман
Является ли ваша среда сборки локальной или облачной?
Лаури Лаанти
@LauriLaanti, наша среда сборки локальная, 1 экземпляр Jenkins с 3 подчиненными.
Симон

Ответы:

7

Сначала пара основных принципов: - Основные изменения всегда должны быть в ветви функций в вашей VCS. - Ветви компонентов должны проходить все тесты до объединения в магистраль. Добавленный - Берет всегда должен строить - Сломанные сборки требуют немедленного действия со коммиттера и / или остальную частью команды. - Неудачный тест должен прервать оставшиеся тесты, только если это критический тест.

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

Вы также можете добавить автоматический тест последней «успешной» сборки (не обязательно такой, которая проходит интеграционные тесты) для тестов пользовательского интерфейса / веб-тестов в виде ночного запуска, который первым делом сообщает об этом утром.

Стив Барнс
источник
3
Барт ван Инген Шенау
@BartvanIngenSchenau - хороший момент добавлен!
Стив Барнс
@ SteveBarnes, спасибо за вклад. Фиксация в Gerrit всегда находится на ветке и объединяется только в случае успеха (мой первый пункт в процессе сборки). После этого начинается проблема. Поскольку 30 разработчиков вносят изменения по нескольку раз в день, нам нужно объединиться рано, а затем проверить. Там есть немедленное действие после того, как сломанные строить, но как время между фиксацией и обратной сборкой составляет 2 часа, будет несколько других фиксациями в то же время. Возможно, сломать следующую сборку.
Симон
@ Симон суть «имя и позор» состоит в том, чтобы заставить ваших разработчиков прекратить совершать испорченный код! На большинстве систем можно выполнить тестовую сборку за короткое время с использованием таких инструментов, как ant, make, scons и т. Д. Если ваш проект хорошо структурирован, большинство языков допускают частичную повторную сборку, чтобы проверить, будут ли что-либо собираться (полная / чистая). сборка еще надо сделать конечно).
Стив Барнс
8

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

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

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

Джон Ву
источник
2
С одной стороны, следует подчеркнуть, что обеспечение стабильности является обязанностью каждого. С другой стороны, я бы посоветовал не публично стыдить, потому что (1) более опытные члены команды несут большую ответственность за помощь младшим членам в достижении стабильности сборки (путем анализа кода, парного программирования или просто тесного сотрудничества перед фиксацией или (исправление сломанной сборки вместе), (2) стыд лишает команду психологической безопасности .
Rwong
1
Если люди не хотят стыдиться, им не следует нарушать строй. Это не так, как неоправданно высокий стандарт. Если у вас есть разработчики, которые не могут его взломать, пусть у них будет своя ветвь для игры, пока они не поймут, как не сломать критический общий состав команды. (Это, как говорится, любой фактический позор должен быть со вкусом).
Джон Ву
В нашем процессе любой коммит разветвлен (в Gerrit) и должен пройти базовый набор тестов, прежде чем слиться с мастером. Эти базовые тесты не могут выполняться в течение часа, так как мы хотим быстро просмотреть и объединить код. После слияния начинается проблема, см. Мой комментарий к @SteveBarnes
Simon
6

Ваша проблема в том, что тесты выполняются слишком долго. К счастью, закон Мура дал нам решение этой проблемы. Сегодня высокопроизводительные серверные процессоры могут легко иметь более 10 ядер (и более 10 HyperThreads). Таких процессоров может быть несколько на одном компьютере.

Если бы у меня были такие длительные тесты, я бы решил проблему с большим количеством оборудования. Я бы купил сервер высокого класса, а затем распараллелил тесты, чтобы тесты полностью использовали все ядра ЦП. Если ваши тесты сегодня однопоточные, то использование 10 ядер и 10 HyperThreds, вероятно, сделает тесты в 15 раз быстрее. Конечно, это означает, что они также используют в 15 раз больше памяти, поэтому на компьютере должно быть достаточно оперативной памяти.

Итак, несколько часов превратятся в 10-30 минут.

Вы не сказали, сколько времени занимает сборка, но стандартные инструменты сборки, такие как make, позволяют распараллеливать сборку. Если вы распараллелите свои модульные тесты, а типичный компьютер разработчика имеет 4 ядра и 4 HyperThreads, то менее чем 10 минут модульных тестов превратятся в менее чем 2 минуты. Итак, возможно, вы могли бы применить политику, согласно которой все должны запускать модульные тесты до совершения?

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

Я не вижу никакой связи между Scrum и вашими проблемами. Проблемы действительно могут возникнуть при любом процессе разработки.

juhist
источник
Я согласен, с более быстрой сборкой все было бы намного проще. Наш TechTeam потратил несколько дней, улучшая скорость нашего процесса сборки, иначе мы бы ждали дни, а не часы. На данный момент эта длительность обратной связи дается в ок. 2 часа. Поэтому я ищу подход, который принимает это как «данное». (Конечно, мы постоянно пытаемся ускорить сборку. Но в ближайшем будущем это будет 2 часа)
Симон
Некоторые тесты могут конфликтовать с параллельным запуском
deFreitas
Можно использовать больше оборудования, только если тесты написаны таким образом, что они могут работать независимо друг от друга без побочных эффектов. Чем дальше вы получаете от оборудования, тем сложнее это получается ... большинство разработчиков не делают этого. сделайте это правильно, поэтому, хотя я согласен с вами, я бы сначала сосредоточился на правильном построении тестов.
c_maker
2

Разве невозможно иметь больше установок Jenkins и заставить разработчиков проверять отдельный экземпляр Jenkins?

Я думаю, что лучшее решение здесь - сделать так, чтобы код прошел все тесты, прежде чем он будет проверен в ветке master и скомпилирован / протестирован основным экземпляром Jenkins. Не позволяйте людям проверять код, который нарушает сборку.

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

xyious
источник
1

Пункт (2) представляется наиболее болезненным, поэтому я остановлюсь на этом.

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

https://en.wikipedia.org/wiki/Dependency_inversion_principle

A. Модули высокого уровня не должны зависеть от модулей низкого уровня. Оба должны зависеть от абстракций.

Б. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.

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

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

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


Как примечание (см. Ответ juhist), вы не можете ускорить сборку (путем распараллеливания), если не разбиваете сборку на отдельные модули.

rwong
источник
0

Я думаю, что вашей команде не хватает одного из ключевых принципов схватки: готового, работающего программного обеспечения. PBI не должен быть помечен как выполненный, пока он не пройдет определение «Готово», установленное вашей командой. Определение Done различно для каждой команды, но, вероятно, будет включать в себя такие вещи, как:

  • Код имеет модульные тесты
  • Модульный тестовый проход как часть автоматизированной сборки
  • Код был объединен с основным (и конфликты были разрешены)
  • и т.п.

Итак, по сути, ваша команда отмечает, что все сделано, а на самом деле не сделано. Это проблема сама по себе.

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

Для TFVC это немного сложнее, потому что все происходит на «дистанционном». Это означает, что разработчики должны всегда работать из веток, если это не быстрое решение. Здесь применяются те же правила, что и в Git: неполное программное обеспечение не фиксируется. Период. В правильно управляемом управлении версиями «main» всегда должен быть выпуская. Если был сделан коммит, который борчит "main", то вы делаете это неправильно.

Крис Пратт
источник