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

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

Цели, которые мотивируют

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

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

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

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

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

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

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

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

Наконец-то у нас появилась возможность выдохнуть.

Преодоление неожиданностей

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

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

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

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

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

Чтобы решить нашу незапланированную работу, мы взяли все на вооружение и разработали план для каждого пункта по мере их поступления:

  • Команда разработчиков начала писать все тесты после того, как команда тестировщиков была сокращена. Работа не может быть завершена без сопроводительного испытания.
  • Мы написали длительные тесты продолжительности, а затем тщательно отладили каждое невыясненное неудачное задание на печать в нашей системе.
  • Мы впихивали исправления из обзоров безопасности, когда могли приспособиться к работе.
  • У нас был один член команды, занимавшийся документированием и регистрацией дефектов против поставщиков.
  • Некоторые члены команды добровольно работают сверхурочно. В худшем случае каждый член команды работал 24 часа в сутки 7 дней в неделю в течение выходных, чтобы уложиться в срок в понедельник. В таких случаях мы брали дополнительные дни для перезарядки.

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

Культура качества прежде всего

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

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

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

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

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

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

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

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

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

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

Постоянное улучшение

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

Один памятный момент подытожил все это, когда менеджер с более чем 35-летним опытом сказал.

Это лучшая команда, в которой я когда-либо работал.

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

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

Все великие дела должны когда-нибудь заканчиваться

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

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

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

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

Я очень надеюсь, что проект станет успешным. Однако на данный момент слишком многое идет против этого. Облачные приложения — это сложные, хаотичные системы, и в лучшем случае те, кто знает их вдоль и поперек, с трудом могут разобраться в них. В отрасли даже существует целое движение под названием DevOps для улучшения практики управления облачным приложением. В худшем случае облачные приложения регулярно выходят из строя или подвергаются компрометации из-за постоянно растущей горы технического долга. Подумайте о том, когда вы в последний раз посещали приложение или веб-сайт, когда вас приветствовало сообщение об ошибке. Лишение проекта команды, которая его создала, означает, что вы также лишаете его знаний о том, как разработать новую функцию или как ее исправить, если что-то пойдет не так. Новая команда всегда способна учиться, но это не гарантия. Иными словами, такие компании, как Google, Facebook, Microsoft, Apple, Netflix и многие другие, предлагают огромные зарплаты и акции инженерам, которые разрабатывают свои наиболее успешные решения, потому что они хотят, чтобы они продолжали работать над этими решениями.

Чтобы забить последний гвоздь в крышку гроба, унылый маркетинг, который у нас был до того, как проект был передан, почти исчез. Не ошибитесь. Проект мертв.

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

История самосовершенствования

В том, как закончился наш проект, нет ничего особенно примечательного или примечательного. Индустрия разработки программного обеспечения постоянно меняется. У стартапов заканчивается финансирование. Проекты сокращаются. Бывает.

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

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

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

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

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

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

  • Успех не зависит от эффективности команды разработчиков. Он зависит от организации в целом. Я думаю, что я уже достаточно заострил внимание на этом вопросе.
  • Не рассчитывайте на вознаграждение за сверхурочную работу. Свободное время, потраченное на этот проект, для меня не имело значения, потому что моя команда была удалена из проекта, и это не имело значения. разница для клиентов из-за предыдущего пункта. Иногда я добавляю дополнительные часы, но обычно, когда я это делаю, я работаю над тем, что хочу, а не над тем, что было приоритетным.
  • Работайте над проектами, которые приносят пользу. Ваша карьера ограничена. Пожалуйста, максимально используйте это.
  • Работайте в компаниях, которые ценят сотрудников и их работу. Вы будете счастливее по очевидным причинам, а компании будут более успешными, потому что они удерживают лучших сотрудников и мотивируют всех сотрудников.
  • Компенсация — это больше, чем деньги, которые вы зарабатываете. Вы учитесь на собственном опыте и извлекаете пользу из крепких отношений и позитивной рабочей культуры. Кроме того, вы сами отвечаете за свою карьеру, поэтому работайте над тем, что вам нравится, что бросает вам вызов и оттачивает ваши навыки.

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

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