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

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

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

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

Практика имела значение. Но не просто практика… практика, которая действительно имела значение, была практикой, в которой она не ощущалась как практика. Лучше всего практиковаться, когда это похоже на реальный жизненный сценарий… в спорте это означало тренировку, как игру, а в программном обеспечении - тестирование, как в производственной среде.

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

Work Harder Corp - Команда 1

Очевидно, название компании вымышленное, но ситуация в команде была такой, как описано.

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

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

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

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

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

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

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

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

Work Smarter Corp - команда 2

Очевидно, название компании вымышленное, но ситуация в команде была такой, как описано.

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

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

  1. Установить Docker
  2. Как извлечь и отправить образы докеров из репозитория образов группы
  3. Как запустить контейнер (ы) локально
  4. Как смонтировать локальные изменения в контейнер

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

У этой команды также было несколько сред, как у первой команды. У них было тестирование, постановка и производство. Как только изменение было зафиксировано в главной ветви, Continuous Integration / Continuous Deployment Pipeline построил код как образ докера, запустил набор тестов, присвоил образу номер версии, поместил образ в репозиторий, а затем заменил docker-контейнеры в тестовой и промежуточной средах автоматически с новейшей версией. Развертывание в производственной среде запускалось вручную при необходимости, но происходил тот же процесс.

Вся эта процедура в плохой день заняла 10 минут.

У всех команд в Work Smarter Corp были похожие настройки.

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

Ключевые отличия:

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

Контейнерное приложение

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

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

Контейнеры действовали как блоки, которые можно было легко и быстро заменить (re: Четыре ключевых показателя. Частота развертывания возросла)

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

Стандартизация / единообразие

В первой команде основные проблемы возникли из-за того, что среда не была стандартизирована.

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

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

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

Мораль рассказа в одном предложении:

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

Работайте умнее, а не усерднее, друзья.

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