Continuous Integration. Путь обеспечения надежности и доверия к системе

Не так давно, я заинтересовался трудами идеологов программирования, таких как Кент Бэк, Роберт Мартин, Мартин Фаулер, Пол Дюваль.

Их книги произвели на меня впечатление и воодушивили попробовать некоторые описанные практики. Refactoring, TDD, XP, и, наконец, Continuous Integration, это то, что в последнее время интересует меня в процессе разработки программного обеспечения.

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

Теория


Continuous Integration (далее CI) — это практика разработки программного обеспечения, в которой члены команды проводят интеграцию не реже чем раз в день. Результаты интеграции проверяются автоматически, используя автотесты и статический анализ кода.

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

Фактически, CI позволяет избавиться от предположений, при процессе разработки ПО. Менеджер предполагает, что продукт готов и стабилен, программист — что в коде нет ошибок и т. д. Избавиться от вопросов, таких как: «стабильна ли последняя сборка, какие фичи готовы, соответствует ли код стандартам компании» и т.д.

Всех, кому интересна тема CI прошу под кат.

Идеологически CI базируется на следующих соглашениях:

  • часто (не менее 1 раза в день) «заливать» свой код в репозиторий
  • писать автоматические тесты
  • запускать private builds(процесс сборки, который выполняется с использованием исходного кода, в данный момент находящегося в локальном репозитории разработчика)
  • не «заливать» неработающий код
  • чинить сломанный build немедленно
  • следить за тем, чтобы все тесты и проверки проходили
  • не выкачивать из репозитория сломанный код


Build script

Скрипт сборки — это набор комманд, которые будут выполнены при запуске процесса интеграции. Чаще всего он выглядит как следующий набор шагов:

  • Очистка от результатов предидущего запуска
  • Компиляция (или статический анализ кода для интерпретируемых языков)
  • Интеграция с базой данных
  • Запуск автоматических тестов
  • Запуск других проверок (соответствие код стандартам, проверка цикломатической сложности и т. д.)
  • Разворачивание программного обеспечения


Автоматические тесты

Всем, кто собирается внедрять CI, придется смириться с тем, что автоматические тесты это неотъемлемая часть процесса непрерывной интеграции. И один лишь статический анализ кода в автоматическом режиме не является Continuous Integration, такой подход называют Continuous Compilation.

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

  • модульные (unit) тесты
  • компонентные тесты
  • функциональные тесты
  • системные тесты


По написанию и запуску тестов также принят ряд соглашений:
  • более быстрые тесты должны запускаться первыми
  • тесты должны быть разделены по категориям
  • на все баги должны писаться тесты
  • тест кейсы стоит ограничивать одной проверкой
  • тесты должны выполняться без ошибок при повторном запуске


На сколько надежна система

За надежность системы отвечает каждый ее компонент, поэтому очень важно уделить повышению надежности системы свое внимание. Я думаю, что никто не хотел бы пользоваться компьютером, который 20% времени не отвечает на ваши запросы. Для того, чтобы продемонстрировать важность надежности представьте себе, что у вас система из 3-х компонентов. Каждый их этих компонентов, надежен на 90%, таким образом общая надежность системы представляет произведение надежностей каждого компонента, итого — 73%. А теперь вспомните, сколько компонентов в последнем написанном вами приложении…

Continuous Inspection

Continuous Inspection — это один из шагов build script, который предполагает проверку соответствия кода в репозитории код стандартам, соответствие уровня code coverage и других метрик заданному порогу.

Continuous Feedback

Одним из самых важных действий в CI является механизм обратной связи, который согласно положениям CI, должен осуществляться с учетом правила: «Правильным людям. В правильное время. Правильным образом.» (ориг. — «The right people. The right time. The right way.»).

Существуют следующие популярные механизмы осуществления обратной связи:

  • SMS
  • browser plug-in
  • светофор сборок
  • звуковое оповещение
  • email


Также, стоит отметить, что многие IDE (NetBeans, PHPStorm), позволяют синхронизироваться с популярными (Jenkins, TeamCity) CI серверами.

Реальность


Так уж случилось, что учавствую в разработке «кровавого энтерпрайз проекта», пришлось адаптировать идеальный вариант CI под реалии сурового мира. К тому времени, как я начал заниматься CI, в распоряжении компании уже были:
  • CI server (Jenkins) с парой десятков билдов
  • модульные тесты, хоть и небольшое колличество
  • скрипты сборки, в основном на shell, но с тенденцией перехода на apache ant
  • стандартный механизм обратной связи — email


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


Решения:
  • доклады по CI и модульному тестированию
  • просветительская работа с каждым разработчиком
  • сотрудничество с QA департаментом
  • изменение в процессе разработки, предполагающее обязательное написание тестов


Планы:
  • улучшить механизм обратной связи, возможно, оставить тот же, предварительно составив для разработчиков алгоритм поиска причин упавшей сборки
  • наладить процесс написания модульных тестов перед кодом, фактически переход на TDD
  • сотрудничество с QA департаментом в целях обнаружения багов еще на этапе составления документации, а также для составления и написания тестовых сценариев


Эпилог

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

Заинтересовавшимся предлагаю прочести книги по CI и смежным или производным от него темам:

Пол Дюваль — Continuous-Integration
Джез Хамбл — Continuous Delivery
Роберт Мартин — Clean Code, Clean Coder
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 8

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

    От прочтения данной статьи возникло море вопрсов.

    Идеологически CI базируется на следующих соглашениях:
    часто (не менее 1 раза в день) «заливать» свой код в репозиторий
    Зачем? Т.е. если я сегодня не залил изменения на сервер, то я поломал CI на предприятии? На мой взгляд важно не регулярно заливать, а регулярно производить сборку.
    запускать private builds(процесс сборки, который выполняется с использованием исходного кода, в данный момент находящегося в
    локальном репозитории разработчика)
    не «заливать» неработающий код
    Это возможно если весь инструментарий CI развернут на машине разработчика, иногда это неудобно — у разработчиков могут быть различные версии ПО (ОС) и т.п. Возможно более удобным решением может оказаться pre-tested commit.
    следить за тем, чтобы все тесты и проверки проходили
    Следить и что?
    не выкачивать из репозитория сломанный код
    Как? Как я узнаю, что среди изменений, которые были залиты другими разработчиками есть сломаных код? И если даже я это и узнаю, то как технически я уговорю свою систему контроля версий это сделать?

    Скрипт сборки — это набор комманд, которые будут выполнены при запуске процесса интеграции. Чаще всего он выглядит как следующий набор шагов:
    Компиляция (или статический анализ кода для интерпретируемых языков)
    Для компилируемых языков статический анилиз тоже может быть успешно использован.
    Разворачивание программного обеспечения
    Могу ошибаться но это уже Continuous Deployment (если речь не идет о разворачивании приложения в Staging Environment для его тестирования).

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

    На сколько надежна система
    Не понял к чему этот раздел.

    Решения:
    доклады по CI и модульному тестированию
    просветительская работа с каждым разработчиком
    сотрудничество с QA департаментом
    Не благоданое это дело…
    изменение в процессе разработки, предполагающее обязательное написание тестов
    Как именно вам этого удалось добиться?

    Планы:
    наладить процесс написания модульных тестов перед кодом, фактически переход на TDD
    Ню-ню ;)…

    Желаю удачи в дальнейшем внедрении и использовании!
      0
      Спасибо за комментарий, очень полезно и интересно узнать мнение других людей на этот счет.

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


      Регулярный апдейт репозитория позволяет быстро узнавать когда и кто сломал билд, следовательно можно вовремя предпринять меры, до выпуска релиза. Часто бывает так, что разработчик комитит изменения локально, за 1-2 дня до релиза начинается всеобщий пуш в релизную ветку, получаем ошибки интеграции. Т.е. как я себе это вижу — постоянное заливание кода в удаленный репозиторий позволяет вовремя среагировать на ошибки, плюс очень дисциплинирует.

      Это возможно если весь инструментарий CI развернут на машине разработчика, иногда это неудобно — у разработчиков могут быть различные версии ПО (ОС) и т.п. Возможно более удобным решением может оказаться pre-tested commit.

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

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

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

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

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

      Могу ошибаться но это уже Continuous Deployment (если речь не идет о разворачивании приложения в Staging Environment для его тестирования).
      Вы правы, здесь речь идет о Staging Environment.

      По написанию и запуску тестов также принят ряд соглашений:
      более быстрые тесты должны запускаться первыми
      Зачем?

      У CI есть одно положение «билд падает быстро». Суть в том, чтобы как можно быстрее узнать о том, что билд сломан, для того, чтобы не менее быстро его починить. Поэтому, тесты и выстраиваются в порядке того, сколько времени занимает их выполнение.

      тесты должны быть разделены по категориям
      Зачем?
      Опять таки, для того, чтобы быстрее понять, что билд сломан. Можно разделять по фичам, по модулям и так далее, и при сборке корректировать в каком порядке запускать тесты.

      На сколько надежна система
      Не понял к чему этот раздел.

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

      Не благоданое это дело…
      Дело конечно кажется неблагодарным, но мне это приносит удовольствие :)
      Как именно вам этого удалось добиться?
      Успешное сотрудничество на уровне менеджмента департамента принесло свои плоды, удалось показать и рассказать в чем же «профит» предлагаемых изменений.

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

        У нас в компании есть следующий подход. Как Вы и описали, можно развернуть часть инструментария CI (продукт состоит из многих модулей, следовательно — разные технологии и т.п.) локально, а можно «постучаться» к билд серверу, на котором уже есть все, кроме того модуля, над которым в данный момент работает разработчик.
        Я хотел обратить внимание, что возмножы ситуации, когда разработчик не сможет обнаружить проблему локально и «зальет» неработающий код. И на мой взгляд это очень сложно обеспечить выполнение требования: не «заливать» неработающий код.

        У CI есть одно положение «билд падает быстро».
        Возможно речь идет о smoke тестах?

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

        Спасибо большое еще раз, за фидбек, если понравиться — у статьи будет продолжение с более детальным описанием каждого процесса и конечно же примерами.
        Пожалуйста, ознакомиться с чужим опытом это всегда интересно.
          0
          Тоже очень хотелось бы увидеть продолжение этой статьи.
            0
            Спасибо, продолжение в процессе написания.
        0
        В целом, я Вашу идею понял, конечно, описан именно идеальный процесс CI, и некоторые его пункты на практике, особенно в больших проектах с легаси кодом и устоявшимися процессами разработки, применить достаточно тяжело.
        Возможно речь идет о smoke тестах?

        Речь скорее о unit тестах, которые как правило выполняются быстрее всех остальных типов тестов.
          0
          Решения:
          •доклады по CI и модульному тестированию
          •просветительская работа с каждым разработчиком
          •сотрудничество с QA департаментом
          •изменение в процессе разработки, предполагающее обязательное написание тестов


          А есть ли измеренные результаты этих решений?
            0
            Если вас интересует на сколько улучшилось качество в «граммах», то, видимо таких цифр я Вам дать физически не смогу — не меряли. Могу как альтернативу сказать, что после того как при разработке нового модуля мы выполнили указанные мной шаги, у нас не было ниодного «мажорного» или «блокед» тикета, количество минорных до десятка, лид стал способен отвечать на вопросы менеджеров о готовности модуля к релизу, на вопросы QA отвечали зеленые билды, а если что-то было не совсем ясно с функционалом — разработчики сразу смотрели тесты испульзуя их в том числе и как документацию. Надеюсь ответил.

          Only users with full accounts can post comments. Log in, please.