0
Обложка: Agile, DevOps, CI/CD. Как менялись концепции разработки

Agile, DevOps, CI/CD. Как менялись концепции разработки

Александр Раковский
Александр Раковский
Senior Java Developer, компания ITentika, N3 group

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

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

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

Больше полувека эта беда преследует крупные программные продукты по всему миру. И, хотя решена эта проблема ещё не везде, лидеры в IT-индустрии, кажется, смогли выработать лекарство от этой болезни.

Водопад

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

Первая в истории иллюстрация инженерного подхода к разработке

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

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

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

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

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

Как правило, обратная связь часто доходила либо слишком поздно, либо не доходила вовсе

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

В 1987 автор известного труда «Мифический человеко-месяц», Фредерик Брукс, в статье «No Silver Bullet» пишет: «Мы видим отчаянные поиски серебряной пули, чего-нибудь, чтобы заставить падать стоимость разработки программного обеспечения также быстро, как стоимость аппаратного обеспечения. Но, смотря на горизонт этого десятилетия, мы не видим серебряной пули».

В 1994-м году не менее известный специалист в области разработки программного обеспечения, автор UML-нотации, Грейди Буч напишет: «Мы часто называем это состояние кризисом программного обеспечения. Но, честно говоря, болезнь, которая длится так долго, должна называться нормой.»

Smalltalk-сообщество

В 80-х годах на базе новейшего тогда, объектно-ориентированного языка появляется сообщество программистов, из которого выйдет целая когорта специалистов, подаривших миру идеи, перевернувшие мир корпоративной разработки программного обеспечения. Это сообщество подарило нам шаблоны проектирования, концепцию рефакторинга, авторов вики, xUnit и TDD. На этом языке были реализованы первые Scrum и XP.

Первый Scrum

В 1993-м году компания Easel начала разработку инструмента для объектно-ориентированного проектирования и анализа. Задача состояла в автогенерации Smalltalk-кода из графических схем и отражении изменений кода обратно на схемы. Этому проекту предшествовало практически десятилетие целенаправленной работы руководителя разработки, Джеффа Сазерленда, в поисках нового процесса, который будет лишён недостатков водопада.

Джефф Сазерленд — автор первого скрама

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

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

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

В то же время исследования показывали, что самая быстрая на тот момент команда в мире, Borland Quattro Pro for Windows, отличалась от остальных запредельным объёмом общения.

Каждый день эта команда из 4, а затем 8 разработчиков проводила несколько часов на встречах, обсуждая разнообразные детали проекта. Основываясь на этом опыте, команда Easel также ввела утренний митинг, позволявший членам команды постоянно придерживаться единого курса. Со временем он сократился до 15-тиминутных стендапов.

Сама команда при этом была намеренно небольшой: все исследования тех лет показывали, что чем больше команда, тем менее она эффективна. Например, одно крупное мета-исследование показало, что небольшие команды, в пересчёте на человека, оказались более чем в 4 раза эффективнее больших.

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

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

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

Уже через пять месяцев исполнительный директор посчитал, что продукт готов к поставке и разработка завершена. В октябре 1995-го года на конференции OOPSLA’95 Джефф Сазерленд и Кен Швабер презентуют всему миру новый процесс, скрам, как набор теперь уже всем известных артефактов: небольшая команда, короткие спринты, планирования, демо, стендапы, скрам-мастер и владелец продукта.

Гипотеза выносливости проекта

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

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

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

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

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

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

Кривые роста функциональности системы со временем в зависимости от качества проектирования

Экстремальное программирование

В 1996 году компания Chrysler перезапускает большой проект по разработке системы начисления заработной платы Chrysler Comprehensive Compensation System (C3), но теперь уже под руководством известного консультанта в области разработки ПО, Кента Бека.

Кент Бек — автор экстремального программирования, TDD, xUnit, первой работы по шаблонам проектирования

Теперь во главу угла была поставлена постоянная борьба со сложностью системы, доведённая до абсолюта. Первая практика гласила: «самое простое, что только может работать».

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

Постоянное изменение уже написанного кода, очевидно, входило в прямое противоречие со всем известной жизненной мудростью: «работает — не трогай». Проблему, вызванную страхом сломать работающий код, решили третьей практикой: написанием разработчиками автоматических юнит-тестов, которые в короткие сроки (до 5 минут) давали быструю обратную связь о корректности работы системы. В попытках довести и эту практику до абсолюта, Кент придумывает подход, когда тестовый код пишется ещё до того, как написан промышленный код. Так появился широко известный Test-Driven Development, дословно, разработка через тестирование.

Процесс TDD обычно описывается в трёх словах: красный, зелёный, рефакторинг

Три эти практики, простота, рефакторинг и TDD, сами по себе переворачивали привычный подход к написанию кода. Они требовали высокой дисциплины и навыка, но редкий разработчик после перехода на них возвращался к программированию «по старинке».

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

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

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

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

Например, рефакторинг подразумевал частые обширные правки по всей кодовой базе. Это приводило к постоянным конфликтам при слиянии веток в системе контроля версий. Решением этой проблемы стала практика непрерывной интеграции (Continuous integration, CI), согласно которой разработчики регулярно, не реже раза в день, вливали свои изменения в главную ветку и проверяли на отдельной машине, что после их изменений не появилось никаких конфликтов, главная ветка все ещё компилируется, а тесты зелёные.

 

Непрерывная интеграция – это именно практика, не технология

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

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

Доведя код-ревью до состояния непрерывности, Кент получил практику парного программирования. Поверх трёх инженерных и четырёх командных практик, Кент выстроил надстройку из менеджерских практик, в заметной степени заимствованных из Scrum. Это были практики небольших релизов, игры в планирование, постоянного контакта с заказчиком («заказчик всегда рядом») и две новые: 40-часовая неделя и метафора.

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

https://tproger.ru/events/setcon-2018/

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

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

Таким образом был выработан набор из практик, доведённых до абсолюта, экстремума; а в 1999-м году Кент Бек опубликовал книгу про дисциплину под названием «Экстремальное программирование», собравшую в себе эти 12 практик:

•    простой дизайн

•    рефакторинг

•    TDD

•    коллективное владение кодом

•    стандарты разработки кода

•    непрерывная интеграция

•    парное программирование

•    частые небольшие релизы

•    40-часовая рабочая неделя

•    заказчик всегда рядом

•    метафора

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

Дисциплина дала старт популяризации таких практик, как TDD, рефакторинг, непрерывная интеграция и коллективное владение кодом.

Экстремальное программирование, его практики и сообщество его сторонников дали старт таким громким и фундаментальным идеям как: Agile, Domain-Driven Design, Behavior-Driven Development, Continuous Delivery.

В число поклонников экстремального программирования вошли мэтры индустрии: Мартин Фаулер, Уорд Каннингхэм, Роберт «Дядюшка Боб» Мартин и многие другие не менее именитые специалисты.

Agile manifesto

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

В 2000-м году Кент Бек организовывает встречу XP-лидеров, которую посетили такие именитые специалисты, как: Мартин Фаулер (Refactoring, PoEAA), Роберт Мартин (Clean Code, SOLID), Дейв Томас (Pragmatic programmer), лидеры в области шаблонов проектирования. На этой встрече ожидаемо зашёл вопрос об организации какого-то сообщества.

Известная фотография со встречи в Сноуберде вот уже больше 20 лет является символом Agile-манифеста

В 2001 году Мартин Фаулер вместе с Робертом Мартином в рамках предложенной идеи созвали 17 программистов, лидеров разных легковесных методологий, созданных в качестве альтернативы пресловутому водопаду. Среди этих методологий были: Scrum, XP, DSDM, Rapid Application Development, Crystal family, Adaptive Software Development, Feature Driven Development, Pragmatic programmers.

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

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

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

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

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

До этапа интеграции какое-то представление о продукте можно было составить лишь по документации. Новые же методологии, напротив, отличало то, что на всем протяжении разработки существовал рабочий прототип, который можно было «потрогать», чтобы оценить прогресс и проверить, насколько первоначальные гипотезы оказались верны. Отсюда вытекала ещё одна ценность, сформулированная в Agile-манифесте: работающий продукт важнее исчерпывающей документации.

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

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

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

В дополнение к 4 ценностям в течение последующих нескольких месяцев авторы в почтовой переписке сформулировали ещё 12 артефактов этого манифеста. Обделённые широким вниманием 12 принципов гибкой разработки раскрывали очень важные нюансы: гибкая разработка — не только про процессы и управление проектом, но и в не меньшей степени про инженерные практики, что было вовсе неудивительно, учитывая, что Agile манифест составляли 17 программистов.

Среди сугубо инженерных принципов были, например:

•    постоянное внимание к техническому совершенству и качеству проектирования;

•    постоянный темп разработки;

•    простота, как искусство минимизации лишней работы.

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

Scrum certification program

В 2002 году один из авторов Scrum, Кен Швабер, с целью популяризации Agile-методологий организовывает программу сертификации Scrum-мастеров. Это были двухдневные платные курсы, погружающие посетителей в основы скрам-методологии.

Свою задачу программа сертификации выполнила сполна: скрам быстро вырвал первое по популярности место у XP и с тех пор стал практически олицетворением Agile в массовом сознании.

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

Это привело к взрыву распространения явления, которое впоследствии один из авторов манифеста, Мартин Фаулер, назвал «вялым скрамом», видимо, в противоположность дословному переводу слова Agile: «ловкий, проворный». Команды начинали работать по скраму, но через некоторое время обнаруживали себя затянутыми в трясину легаси из-за недостаточного внимания к ключевым техническим практикам: простому дизайну, рефакторингу и автоматическому тестированию.

Это явление впоследствии другой автор Agile назовёт «Тёмным Agile», а сам создатель скрама, Джефф Сазерленд, начнёт регулярно упоминать, что скрам наиболее эффективен в комбинации с техническими практиками, например, с XP. Но, к сожалению, даже сейчас, спустя 20 лет, «вялый скрам» и «тёмный аджайл» вместе с водопадом остаются крайне распространёнными методологиями разработки программного обеспечения.

Мартин Фаулер. Участник первого XP-проекта, автор огромного количества важнейших книг-мастридов

Бурное десятилетие Agile-комьюнити

В то же время каноничная agile-разработка продолжала развиваться в своём направлении. В 2001-м году авторы Agile-манифеста и участники первого XP-проекта, Мартин Фаулер в паре с Кентом Беком, выпускают книгу, описывающую одну из практик экстремального программирования: Рефакторинг.

Через год за авторством того же Мартина Фаулера выходит книга по архитектурным шаблонам разработки корпоративных приложений, в которой были описаны такие ключевые паттерны, как: Data Mapper (ORM), Контроллер, Репозиторий, Сервисный слой, Гейтвей, 3-х и 2-х слойная архитектура и, самое важное, шаблоны Транзакционный скрипт и его антипод — Доменная модель.

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

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

Эти 3 книги подарили базовый набор шаблонов и практик для проектирования систем в agile-стиле, став альтернативой классическому подходу предварительного проектирования. В 2004-м году Мартин Фаулер описывает новый agile-подход к проектированию в своей эпохальной статье «Is Design Dead»?.

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

Так зародилась концепция BDD (Behavior Driven Development), которая настолько прочно срослась с идеей исполняемых спецификаций (Cucumber, Specflow или FITnesse), что сейчас многими эти два термина воспринимаются как синонимы.

Иллюстрация гексагональной архитектуры из оригинальной статьи Алистара Кокберна

На основе концепций исполняемых спецификаций и DDD в 2005-м году один из авторов Agile, Алистар Кокберн, формулирует важнейшую идею Гексагональной архитектуры, которая легла в основу другой концепции, сформулированной уже другим автором Agile, Чистой Архитектуры.

Continuous Delivery

Ещё в 1998-м году в одной швейцарской страховой компании Кент Бек простроил процесс разработки, по которому каждый день после ночных тестов приложение разворачивалось в промышленную эксплуатацию. Эту практику, наверное, можно назвать первой в истории «непрерывной поставкой». Через 12 лет Джез Хамбл и Дейв Фарли публикуют книгу «Continuous Delivery», в основу которой лёг многолетний опыт их работы в компании Thoughtworks, до сих пор являющейся одним из мировых лидеров в области Agile-разработки.

Дейв Фарли — соавтор книги Continuous Delivery, один из пионеров XP

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

Ещё в начале экстремального программирования юнит-тесты и приёмочные тесты (функциональные и нефункциональные) представляли из себя две разные сущности.

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

Задача приёмочных тестов была в том, чтобы перед релизом дать ответ на вопрос, выполняет ли система поставленные перед ней требования.

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

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

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

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

Таким образом, одна команда может развёртываться в продакшн десятки раз в день. Можно проследить, как эта практика работает в масштабе таких гигантов, как Amazon: уже 11 лет назад, в 2011 году, эта компания вводила в эксплуатацию новые изменения, в среднем, каждые 11, 6 секунд. Ещё тогда за час Amazon производил до 1079 развёртываний.

Пример пайплайна с сайта Continuous Delivery

Именно эта практика и была описана в книге «Непрерывная поставка» (Continuous Delivery), центральным элементом которой стал шаблон «Конвейер развёртывания» (Deployment pipeline), представлявший из себя последовательный запуск сборки, CI-тестов, развёртывания на тестовый стенд, приёмочных тестов и развёртывания в промышленную эксплуатацию.

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

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

Через конвейер должен проходить каждый бит того программного обеспечения, которое идёт в эксплуатацию. На практике это обеспечивалось локальными репозиториями библиотек и иных артефактов вплоть до самих операционных систем. Собственно, отсюда началось развитие таких технологий контейнеризации, как Docker.

Настолько суровые требования позволяли обеспечить быстрый откат системы на работающую версию в самых разных случаях: при дефектах в коде, требованиях бизнеса, неправильной конфигурации инфраструктуры или приложения и при проблемах с новыми версиями сторонних зависимостей (баг в библиотеке или даже в операционной системе). Сама практика получила название «Инфраструктура как код» и стала неотъемлемым атрибутом непрерывной поставки.

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

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

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

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

DevOps

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

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

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

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

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

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

Иллюстрация, показывающая разделение ответственности между разными группами специалистов

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

Jez Humble, соавтор книг Continuous Delivery и Accelerate, соавтор отчёта State of DevOps

DORA metrics

В 2013-м году выходит первый отчёт под названием State of DevOps, ставший очередной важнейшей вехой в истории развития разработки программного обеспечения. Задачей авторов отчёта стало определение метрик, которые позволят измерить производительность команд и их влияние на экономические показатели компаний.

Опросив 4 тысячи специалистов по всему миру, авторы исследования с помощью методов статистического анализа обнаружили сильную корреляцию между 4-мя метриками:

— частота релизов — от «по требованию (несколько раз в день)» до «реже одного раза в полгода»;

— время от коммита до деплоя в продакшн — от «меньше одного часа» до «больше полугода»;

— среднее время на восстановление после отказа;

— частота возникновения проблем при изменениях в проде (в т.ч. новые релизы или изменения конфигурации).

Первые две метрики авторы отнесли к группе «Пропускная способность», последние две — к группе «Стабильность».

Статистический анализ показал, что по этим 4 метрикам команды явно бьются на 3 крупных кластера (данные отчёта за 2016-й год):

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

Организации, в которых работала первая группа команд, в два раза более вероятно превосходили свои цели по прибыльности, доле на рынке, удовлетворённости клиентов и иным экономическим и организационным показателям. Также первая группа команд в среднем тратила на 26% меньше времени на незапланированную работу и переделки и на 44% больше времени на новую работу.

Эти и многие другие результаты дали этим группам команд соответствующие названия: «высокопроизводительные», «среднепроизводительные» и «низкопроизводительные».

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

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

Что касается автоматизации тестов, исследование подтвердило, что следующие практики предсказывают высокую IT-производительность:

•    Наличие надёжных (!) автоматических тестов. Это означает, что когда тесты проходят, команда уверена в том, что изменения можно безопасно деплоить. Более того, команда уверена, что упавший тест означает реальную проблему, а не проблему в тестах или окружении.

•    Приёмочные тесты пишут и поддерживают разработчики. Также важна возможность легко воспроизвести и починить их на локальной машине. Тут важно то, что автотесты, написанные QA или отдельной командой, с IT-производительностью не коррелируют – тесты должны писать именно разработчики.

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

Не менее важной практикой высокопроизводительных команд оказалась работа на одной ветке (trunk-based development) с регулярными (чаще одного раза в день) слияниями с мастером, пришедшая из практики непрерывной интеграции.

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

Этот результат серьёзно копает под популярную методику разработки GitFlow, где разработчики работают на изолированных друг от друга feature-ветках. Впрочем, как подчёркивают авторы доклада, подход с feature-ветками идеально подходит для open-source разработки, для которой он, собственно, и разрабатывался.

Также высокую производительность предсказывали следующие утверждения:

•    способность в любой момент провести все (или почти все) необходимое тестирование без интеграции с другими компонентами и командами;

•    способность в любой момент деплоить приложение независимо от других сервисов и приложений;

•    способность вносить широкомасштабные изменения в архитектуру системы без разрешения кого-либо за пределами команды;

•    способность вносить широкомасштабные изменения в архитектуру без зависимости от других команд;

•    выполнение работы без координации с людьми за пределами команды;

•    развёртывания в рабочие часы с пренебрежимо малым временем недоступности сервиса.

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

•    все изменения, идущие в продакшн, должны быть одобрены кем-то за пределами команды;

•    только высоко-рискованные изменения (например, изменения базы данных) должны быть одобрены;

•    мы полагаемся на внутрикомандное ревью изменений;

•    у нас нет никакого процесса одобрения изменений.

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

Список спонсоров отчёта

Важность этого отчета и его результатов для всей индустрии трудно переоценить. На данный момент многие крупные компании используют эти метрики или их вариации для определения эффективности команд. Например, в спонсорах этого отчета отметились такие компании, как Amazon, Google, Atlassian, Microsoft, GitLab, vmware, Hewlett Packard, New Relic, Pivotal, Splunk и другие.

Заключение

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

Однако, несмотря на свои достижения, перед этим движением до сих пор стоит важнейшая задача борьбы с заблуждениями о своей природе. Так соавтор Agile-манифеста, Мартин Фаулер, в своем докладе «Agile in 2018» сформулировал 3 главные проблемы, которые стоят перед Agile-сообществом:

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

•    недооценка важности технических практик. Мартин в очередной раз напоминает, что Agile без технических практик невозможен — он на них стоит.

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

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