Непрекъсната интеграция

Непрекъснатата интеграция (Continuous integration – CI) е практика в софтуерното инженерство, за обединяване на всички копия, по които програмистите работят, в споделена главна линия няколко пъти на ден. За първи път е наименована и предложена от Грейди Бууч в метода му от 1991 г.,[1] въпреки че Бууч не се застъпва за интегрирането няколко пъти на ден. То е прието като част от екстремното програмиране (XP), което подкрепя интегрирането повече от един път на ден, а дори и десетки пъти на ден. Основната цел на CI е да се предотвратят интеграционни проблеми, посочени като „интеграционен ад“ в ранните описания на XP. CI не е всеобщо приета като подобрение в сравнение с честата интеграция, така че е важно да се прави разлика между двете, тъй като съществува известно несъгласие относно достойнствата им.[citation needed]

В XP, CI е предназначена да се използва в комбинация с автоматизирани тестове на ниво отделна градивна единица, написани чрез практиките на разработка чрез тестове. Първоначално това е било замислено като изпълнение на всички тестове на ниво отделна градивна единица в локалната среда на разработчика и проверка дали всички те са минали, преди качване на основната линия. Това помага да се избегнат случаи, при които текущата работа на един разработчик счупва копието на друг разработчик. Ако е необходимо, частично готовите функции могат да бъдат изключени преди да се извърши качването с помощта на превключвачи на функции (feature toggles).

При по-късни разработки на концепцията се въвеждат билд сървърите, които периодично, или дори след всяко качване автоматично изпълняват тестовете на ниво отделна градивна единица и изпращат резултатите към програмистите. Използването на билд сървъри (не задължително изпълняващи тестове на ниво отделна градивна единица) вече е практикувано от някои отбори извън XP общността. В днешно време, много организации са приели CI, без да са приели изцяло XP.

В допълнение към автоматизираните тестове на ниво отделна градивна единица, организациите, използващи CI, обикновено използват билд сървъри за изпълнението на непрекъснати процеси на прилагането на качествен контрол като цяло – малко количество усилия, прилагани често. В допълнение към изпълнението на тестове на ниво отделна градивна единица и интеграционните такива, подобни процеси изпълняват допълнителни статични и динамични тестове, измерват и профилират производителност, извличат и форматират документация от програмния код и улесняват процесите на ръчно осигуряване на качеството. Това непрекъснато приложение за качествен контрол цели да повиши качеството на софтуера, както и да намали времето, необходимо, за неговото изпълнение, като се заменя традиционната практика на прилагане на качествен контрол след завършването на цялото разработване. Това е много сходно с първоначалната идея за по-често интегриране, за да се направи интегрирането по-лесно, прилагана само за процеси, свързани с осигуряване на качеството.

В същия дух, практикуването на непрекъснато качване на код допълнително разширява CI, като се проверява, дали софтуерът, качен на главната линия, винаги е в състояние да се внедри при потребителите и прави същинския процес на внедряване много бърз.

Работен процес редактиране

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

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

В крайна сметка, хранилището може да стане толкова различно от оригиналните версии на разработчиците, че те навлизат в това, което понякога се нарича „ад на сливането“, или „интеграциионен ад“ [2], където времето, необходимо, за да се извърши интеграцията, надвишава времето, което е било необходимо, за да се направят първоначалните промени. В най-лошия случай, на разработчиците може да се наложи да отхвърлят направените промени и напълно да преправят работата си.

Непрекъснатата интеграция предполага да се интегрира рано и често, за да се избегнат капаните на „интеграционния ад“. Практиката има за цел да се намалят преработките и по този начин да се намалят разходите и времето.

Допълнителна практика към CI е, че преди да се качи работата, всеки програмист трябва да направи пълен билд и да изпълни (успешно) всички тестове на ниво отделна градивна единица. Интеграционните тестове  обикновено се стартират автоматично на CI сървъра, когато той открие ново качване.

Добри практики редактиране

В тази част от статията са разгледани добрите практики за постигане на непрекъсната интеграция и относно това как може да бъде автоматизирана. Автоматизирането на билдове (build automation) е най-добрият начин за това. [3][4]

Непрекъсната интеграция – практиката, при която нов или променен код се добавя към главното хранилище за програмен код, трябва да се изпълнява достатъчно често, за да не остава по-дълъг период между качването и билдването, а и за да не възникнат грешки, които да останат незабелязани и некоригирани своевременно от програмистите. [5] Нормално е да се прави билд след всяко качване в главното хранилище за код, отколкото той да се прави периодично. Много инструменти предлагат това автоматизирано периодично качване.

Друг фактор е нуждата е от система за контрол на версиите (Version control system), която да поддържа атомични качвания, т.е. всички промени на един програмист могат да бъдат видени като едно-единствено качване. Няма смисъл да се прави билд само от половината от променените файлове.

За да се постигнат тези цели, непрекъснатата интеграция се осланя на следните принципи.

Поддържане на хранилище с код редактиране

Тази практика застъпва използването на revision control системите в сорс кода на проекта. Всички елементи, необходими за създаването на проекта, трябва да бъдат в хранилището на кода. Чрез тази практика и сред хората, които използват revision control системи, съществува конвенция, че системата трябва да може се билдва чрез ново сваляне и да не изисква допълнителни зависимости. Мартин Фаулър, който горещо подкрепя екстремното програмиране, също споменава, че където използването на клонове на разработчиците се осъществява чрез инструменти, неговата употреба трябва да бъде минимална.[5] Вместо това се препоръчва промените да бъдат интегрирани, отколкото да се поддържат едновременно няколкото версии на софтуера. Главната линия трябва да бъде мястото, където се намира работещата версия на софтуера.

Автоматизиране на билда редактиране

Една-единствена команда трябва да може да билдва цялата система. Много инструменти за билдване като „Make“ съществуват от доста години. Много други по-скорошни инструменти са често използвани в средите на непрекъсната интеграция. Автоматизирането на билда трябва да включва и автоматизиране на интеграцията, което често в свързано с внедряването в нещо като тестова среда, която да имитира реална такава. В много случаи скриптът за билдове не само компилира бинарен код, но също създава документация, уеб страници, статистика и медия за разпространение (като Debian DEB, Red Hat RPM или файлове за Windows MSI).

Създаване на самотестващ се билд редактиране

Щом един път кодът е билднат, всички тестове трябва да се изпълнят, за да се установи, че всичко работи, както програмистът очаква.

Всеки качва в хранилището всеки ден редактиране

Чрез редовното качване всеки, който качва, може да намали броя на конфликтните промени. Качването на работа, която е свършена за седмица, води до риск от конфликти с други функционалности и това може да бъде много трудно за разрешаване. По-рано подобни малки „конфликти“ в част от системата са принуждавали членовете на екипа да сигнализират за промените, които правят. Качването на всички промени поне веднъж на ден (един път за всяко билдване на функция) като цяло се смята за част от дефиницията на непрекъснатата интеграция. Също така се препоръчва и билдване всяка нощ. Това е долната граница; честотата трябва да бъде дори по-голяма.

Всяко качване (в хранилището) трябва да бъде билднато редактиране

Системата трябва да билдва качванията към настоящата работеща версия, за да се провери дали се интегрират правилно. Честа практика е използването на Автоматизирана Непрекъсната интеграция, въпреки че това може да се извърши и ръчно. За много хора непрекъснатата интеграция е синоним на Автоматизирана Непрекъсната интеграция, при която сървър за непрекъсната интеграция или демон следи системата за контрол на версиите за промени, след което автоматично се стартира процеса на билдване.

Осигуряване на бързина на билда редактиране

Билдът трябва да се осъществява бързо, защото при проблем с интеграцията, той трябва да бъде намерен бързо.

Тест в копие на средата на разработка редактиране

Използването на тестова среда може да доведе до грешки в тестваните системи, когато са внедрени в продукционна среда, тъй като тази продукционна среда може да се различава значително от тестовата такава. Въпреки това, създаването на копие на продукционната среда е забранено, заради високата си цена. Вместо това тестовата среда или друга постпродукционна среда („staging“) е добре да се създаде така, че да е умалена версия на истинската продукционна среда, за да се намалят разходите, като едновременно се запази архитектурата и нюансите на технологията.

За лесни резултати редактиране

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

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

Всеки има достъп резултатите от най-новия билд редактиране

Трябва лесно да се разбира дали билдът се чупи и ако е така, кой е направил съответната промяна.

Автоматично внедряване редактиране

Повечето системи за CI позволяват изпълнението на скриптове след завършване на билда. В повечето ситуации е възможно да бъде написан скрипт, който да внедри приложението към сървър, който има възможност за тест в реално време и до който всички имат достъп.[6][7]

История редактиране

През 1994 г. Грейди Бууч използва фразата непрекъснато интегриране в „Обектно-ориентираният анализ и дизайн с приложения“ (второ издание),[8] за да обясни как, когато се работи, използвайки процеси на ниско ниво, „вътрешните продукти са един вид непрекъсната интеграция на системата и съществуват, за да спрат насила процесите на ниско ниво“. През 1997 година Кент Бек и Рон Джефрис измислят Екстремно програмиране (XP), докато участват в проект на Системата Крайслер Комприхенсив Компенсейшън който включва непрекъснато интегриране.[9] Бек публикува материал за непрекъснатото интегриране през 1998 г., като акцентира върху важността на комуникацията „лице в лице“, в сравнение с технологичната помощ.[10] През 1999 г. дава допълнителна информация в неговата първа цялостна книга „Екстремно програмиране“.[11] Круиз Контрол е пуснат през 2001 г.

Предимства и недостатъци редактиране

Непрекъснатото интегриране има следните предимства:

  • Интеграционните грешки се установяват рано и са лесни за проследяване, заради малкото пакети с промени. Това спестява както време, така и пари по време на продължителността на живот на проекта.
  • Избягва се хаосът, когато идва крайният срок на проекта и всеки се опитва да качи своята леко несъвместима версия.
  • Когато компонентните тестове се провалят или се появи грешка, ако разработчиците трябва да върнат без дебъгване базата с код към по-ранна версия, в която няма грешки, само малък брой промени се губят (защото интегрирането се случва често).
  • Постоянно наличие на „текущи“ билдове за тестове, демонстрации или с цел пускане на работеща версия.
  • Честото обновяване на кода кара разработчиците да създават модуларен код, който е по-малко комплексен.

С непрекъснатото автоматично тестване предимствата мога да включват:

  • Налагане на дисциплина за периодично автоматично тестване
  • Моментна обратна връзка за влиянието на локалните промени върху цялата система
  • Измервания, получени от автоматичното тестване и CI (например измервания за кодово покритие, сложност на кода и цялостни функции) помагат на програмистите да се концентрират върху разработката на функционален и качествен код и подпомагат набирането на инерция в един отбор.[citation needed]

Конструирането на автоматична система за тестове изисква значително количество работа, включително продължителни усилия за създаването на нови функции и проследяването на умишлени промени в кода. Тестването само по себе си се счита като най-добрата практика при разработка на софтуер, независимо дали се използва непрекъсната интеграция, а автоматизацията е неразделна част от методологиите за проекти, като разработването чрез тестване. Непрекъснатата интеграция може да бъде извършвана без никакви тестове, но цената на осигуряване на качеството, за да се създаде работещ краен продукт, може да бъде висока, ако се наложи да се извършва често или на ръка. Изисква се определено количество работа за създаването на билд система и автоматично тестване, ако те ще се прилагат, но съществуват множество проекти със софтуер за непрекъсната интеграция – платени или с отворен код, които могат да се използват.

Източници редактиране

  1. Booch, Grady (1991).
  2. Cunningham, Ward (5 август 2009).
  3. Brauneis, David (1 януари 2010).
  4. Taylor, Bradley.
  5. а б Fowler, Martin. Practices // Continuous Integration. Посетен на 3 октомври 2011.
  6. Ries, Eric (30 март 2009).
  7. Fitz, Timothy (10 февруари 2009).
  8. Booch, Grady (December 1998).
  9. Fowler, Martin (1 май 2006).
  10. Beck, Kent (1998-03-28).
  11. Beck, Kent (1999).