Тестовете, които изядоха пускането: когато вдигането на лимита скрива причината
От Dorian Chávez · съосновател и главен изпълнителен директор на Hábil ·
Пет седмици разумни кръпки и спряно пускане: защо вдигането на лимита на build-а не премахва причината и кои три правила трябва да изисква вашият комитет.
Един петък в 19:05 новата версия на корпоративния сайт не излезе: build-ът вървеше от 99 минути при лимит от 100, а на 100-ната минута системата го прекъсна.
Build-ът е конвейерът за доставка (pipeline): компилира, пуска пакета от автоматизирани тестове и подготвя версията. Нито един тест не се провали. Просто не завършиха навреме, а веригата за доставка направи това, което трябваше: спря. Версията носеше промяна в текст и поправка във формуляра за контакт, а маркетингът се нуждаеше от нея същия ден: в понеделник започваше кампания.
В канала на екипа някой написа това, което всички си мислеха: «Ами ако го вдигнем на 120?».
Въпросът към вас е друг: колко пъти тази година екипът ви е вдигал времеви лимит и в колко от тези случаи някой е попитал защо е било нужно?
Едно уточнение, преди да започнем: това е хипотетичен и илюстративен сценарий. Екипът, сайтът и цифрите са измислени и не описват нито един клиент на Hábil. Моделът се среща в много екипи и обикновено започва по един и същи начин: дефект в дизайна, прикрит с кръпка, която звучи разумно. Онова, което идва от публикувани източници, носи своя номер на източник; когато нещо е наш прочит, го казваме.
За 1 минута
- Рискът: продължителността на тестовете да се третира като проблем на конфигурацията: всеки път, когато доставката наближи лимита, някой вдига лимита, а причината продължава да расте.
- Случаят: за пет седмици лимитът на build-а стигна от 30 до 100 минути. Причината беше там от първия ден: всеки тестов файл изграждаше целия сайт наново, преди да провери своята част. Нито една кръпка не я засегна.
- Цената на бездействието: спряно пускане в деня, в който бизнесът се нуждаеше от него, кампания без страница и екип, който престава да вярва на собствените си аларми. За проверката, която върви при всяка промяна, Fowler цитира ориентир от около десет минути [1], а DORA — лимит от около 10 минути за тестовете [2]; в този екип етапът на тестовете стигна около 58 минути, а лимитът — сто.
- Какво да решите в понеделник: продължителността на тестовете да има бюджет и да се сравнява версия срещу версия и да не се приема кръпка, която не обяснява причината, независимо дали я предлага човек, или асистент с изкуствен интелект.
В тази статия
- Какво се случи в петъка, когато версията не излезе?
- Как се стигна до сто минути за пет седмици?
- Каква беше истинската причина?
- Защо нито една кръпка не реши проблема?
- Какво казва практиката в индустрията за това колко трябва да отнема едно пускане?
- Кои три правила променят историята?
- Каква роля изигра изкуственият интелект?
- Как изглежда скучната версия на тази история?
- Ключови изводи
- Какво прави Hábil?
- Често задавани въпроси
Какво се случи в петъка, когато версията не излезе?
Пускането не спря заради грешка в кода: спря, защото тестовете продължиха повече от времето, което им беше позволено.
Струва си от самото начало да разделим два часовника, защото в тази история лесно се бъркат:
| Часовник | Какво измерва | Кой го определя |
|---|---|---|
| Лимитът на build-а | Максималното време, което може да отнеме целият конвейер: компилиране, пакетиране, пускане на тестовете и подготовка на версията. Ако бъде надхвърлено, системата прекъсва всичко. | Един ред конфигурация, който екипът може да промени за секунди |
| Продължителността на етапа на тестовете | Колко наистина продължават тестовете вътре в този build | Дизайнът на тестовете: колко са, как се подготвят и колко работа повтарят |
Лимитът е разрешение. Продължителността е факт. Вдигането на разрешението не променя факта; променя само кога ще научите за него.
Сайтът беше корпоративният сайт на средно голяма компания: няколко страници на испански и английски, един формуляр и раздел с новини. Нищо критично за мисията. Затова случаят е полезен: същият модел може да засегне по-критични системи, с въздействие, което зависи от тяхната архитектура, от наличния капацитет и от дизайна на тестовете им.
През седмица 5 етапът на тестовете беше около 58 минути при нормални условия; останалата част от пълния build се добавяше към тази цифра. В онзи петък освен това друг конвейер заемаше същата машина за интеграция: пълният build, с всичките си етапи и чакането за ресурси, стигна 100-те минути на лимита и спря. Споделената машина беше тласъкът, не причината: един здрав пакет от тестове щеше да продължи повече, но далеч от лимита. Този вече живееше толкова близо до лимита, че всяко допълнително натоварване стигаше, за да го прекрачи.
Как се стигна до сто минути за пет седмици?
С пет решения, които едно по едно имаха смисъл, и нито едно от които не попита защо отнема толкова време.
| Седмица | Какво се наблюдаваше | Какво се реши | Лимит на build-а |
|---|---|---|---|
| 1 | Етапът на тестовете отнема около 12 минути, с около 60 тестови файла | Нищо: всичко се побира с резерв | 30 мин |
| 2 | Пакетът от тестове расте с всяка нова функционалност; един ден пълният build надхвърля 30 минути | Вдигане на лимита | 50 мин |
| 3 | Четири файла са особено бавни; някои тестове започват да се провалят от време на време, без видима причина | Разделяне на 4-те файла на 13 по-малки и повече време за всеки тест | 50 мин |
| 4 | Преди корекцията етапът е около 40 минути, а машината за интеграция се претоварва | Намаляване на паметта на всеки процес, на броя процеси, които вървят паралелно, и вдигане на лимита | 75 мин |
| 5 | Вече са около 230 файла. След корекцията от седмица 4 и с почти същите тестове етапът минава от около 40 на около 58 минути при нормални условия | Ново вдигане на лимита | 100 мин |
Екипът използваше асистенти с изкуствен интелект, за да генерира голяма част от кода и от тестовете, и всяка нова функционалност идваше със своя тест. Това изглеждаше като дисциплина. Всеки ред от таблицата имаше обяснение, което звучеше добре: «пакетът порасна», «големите файлове са бавни», «машината се задушава». И никой не зададе единствения въпрос, който имаше значение: защо отнема толкова време?
Каква беше истинската причина?
Всеки тестов файл изграждаше целия сайт наново, преди да провери своята част: цена, която трябваше да се плати веднъж, се плащаше двеста и трийсет пъти.
Уликата беше в таблицата през цялото време. Вижте седмица 5: почти същите тестове, около 18 минути повече. Тъй като обхватът на тестовете се беше променил малко, разумната хипотеза беше, че тези минути идват от начина, по който се изпълняват, а не от това, което се тества. Една хипотеза се потвърждава с измерване: като се отделят времето за подготовка, времето за тестване и чакането за ресурси. В сценария това измерване показва, че почти всичко е било подготовка.
За да провери, че един бутон казва «Send» в английската версия, тестовият файл правеше всичко това: компилираше сайта, генерираше всичките му страници на двата езика, пускаше го да работи и едва тогава поглеждаше бутона. Следващият файл, за същия бутон на испански, повтаряше всичко от нулата. И следващият. Около двеста и трийсет пъти.
Все едно сградата да се строи отново, преди да се провери всяка крушка.
При 60 файла тази повтаряна цена не болеше, а тъй като никой не измерваше колко отива за подготовка и колко за тестване, никой не я видя. С всеки нов файл тя растеше пропорционално. Това е вроденият дефект: не беше проблем на седмица 5; беше дизайн, който още от седмица 1 вграждаше повтаряна цена, която щеше да расте с всеки нов файл.
С това наум всяка кръпка се чете различно:
- Разделянето на 4 файла на 13 превърна 4 изграждания на сайта в 13.
- Намаляването на паралелизма накара тези изграждания да вървят повече на опашка и по-малко едновременно.
- Вдигането на лимита даде повече въже на всичко изброено.
Провалите «без причина» от седмица 3 също имат друг прочит. В сценария те съответстваха на претоварена машина. Google документира през 2016 г., че сред няколкото възможни причини за тестовете, които понякога минават, а понякога се провалят при същия код, са конкурентността (няколко теста, които се борят за едно и също нещо едновременно) и проблемите с инфраструктурата [3]; потвърждаването на това в конкретен случай изисква метрики и журнали от изпълнението. Даването на повече време без измерване не ги излекува: отне им гласа.
Защо нито една кръпка не реши проблема?
Защото всички се занимаваха със симптома (часовника) и нито една с работата, която се повтаряше.
Нито една кръпка не беше погрешна сама по себе си; на всички им липсваше измерване, преди да се реши.
| Какво се направи | Какво наистина прави | Какво не прави |
|---|---|---|
| Вдигане на лимита на build-а (30 → 50 → 75 → 100 мин) | Дава повече резерв преди прекъсването | Не премахва нито една секунда работа |
| Разделяне на файлове (4 → 13) | Разпределя работата на повече парчета, които могат да вървят едновременно | Ако всяко парче изгражда сайта наново, умножава повтаряната цена |
| Намаляване на паметта и паралелизма | Може да облекчи претоварване, ако се потвърди с измерване | Не премахва работа: нарежда я на опашка. Тук — от около 40 на около 58 минути при почти същите тестове |
| Повече време за всеки тест | Толерира нормалните отклонения | Ако се прави без измерване, скрива влошаването и превръща алармата в тишина |
Времевият лимит работи като детектор за дим. Ако го вдигате всеки път, когато се включи, няма по-малко огън: има по-малко предупреждение.
Google го описва с цифри от собствената си работа: около 1,5 % от всички изпълнения на тестове са отчитали нестабилен резултат, а почти 16 % от тестовете са имали някаква степен на нестабилност [3]. Най-важното за вас е последствието, което посочват: при толкова много фалшиви положителни резултати често се случва истински провали да бъдат пренебрегнати [3]. И предупреждават, че автоматичното отделяне на нестабилните тестове може лесно да замаскира истинска грешка в кода [3]. Търпимостта към една аларма има цена, дори да не се появява в нито една фактура.
Затова поуката от тази история не е «пакетът растеше, докато се счупи». Тя е по-неудобна: роди се с дефекта и всяка кръпка, която не измери причината, го направи по-бавен.
Какво казва практиката в индустрията за това колко трябва да отнема едно пускане?
Че проверката, която върви при всяка промяна, трябва да е около десет минути и че когато започне да расте, се действа веднага, а не когато вече не се побира.
Martin Fowler в статията си за непрекъснатата интеграция възприема ориентира на екстремното програмиране (XP) за build от десет минути и казва, че за повечето проекти той е напълно разумен [1]. И препоръчва времената на build-а да се следят и да се действа веднага щом започнат да надхвърлят правилото на десетте минути [1]. Той също отбелязва, че поне при корпоративните приложения обичайното тясно място са тестовете [1].
DORA описва непрекъснатата интеграция с подобни думи: тестовете трябва да вървят за няколко минути, с горна граница от около 10 минути [2]. И определя дисциплина за екипа: ако автоматичните тестове се провалят, екипът спира това, което прави, за да ги поправи веднага; ако build-ът не може да се поправи за няколко минути, промяната, която го е счупила, се установява и се връща назад [2]. DORA изисква освен това тестовете да са надеждни и бързи, за да дават обратна връзка възможно най-рано, и предлага по-дългите тестове да се изнесат в отделен build [2]. Внимание с разликата: решението кои тестове вървят при всяка промяна и кои в друг момент е дизайнерско решение, взето предварително; изнасянето им, защото вече не се побират, е просто още един вдигнат лимит.
Поставено до сценария:
| Източник | Какво предлага | Какво преживя екипът |
|---|---|---|
| Fowler [1] | Build от около десет минути; да се действа веднага щом го надхвърли | Етап на тестовете от 12 до 58 минути; лимитът беше вдигнат от 30 на 100 и никой не предприе нищо за продължителността |
| DORA [2] | Тестове от няколко минути, с лимит от около 10 | Етап на тестовете от 12 до 58 минути |
| DORA [2] | Ако build-ът се счупи, се поправя или се връща назад за минути | Когато се чупеше, лимитът се вдигаше |
Нашият прочит: десет минути не са магическо число, но практиката ясно показва, че продължителността се следи и се защитава като свойство на системата, а не като поле, което се нагласява, когато пречи.
Кои три правила променят историята?
Нито едно не е ред в конфигурацията: и трите са преценка и се побират в инженерна политика от една страница.
Правило 1. Скъпото се подготвя веднъж и се използва повторно, докъдето е безопасно
Ако тестовете се нуждаят от изградения сайт, от база данни с примерни данни или от стартирана услуга, определете какво може да се подготви веднъж и да се споделя, без да се нарушава изолацията между тестовете.
Онова, което не се променя, като вече изграден сайт, се използва от всички тестове; онова, което се променя, като база данни, се изолира или се нулира по контролиран начин. Никой не изгражда света наново, за да погледне един бутон.
Това не е нова идея. Съвременните рамки за тестване предвиждат място за глобална подготовка: функция, която се изпълнява веднъж преди всички тестове [4][5], или ресурси, чийто обхват е цялата тестова сесия, а не всеки отделен тест [6]. Документацията на една от тях посочва, че ресурсите, които изискват мрежов достъп, обикновено са скъпи за създаване [6]. Механизмът се променя от инструмент на инструмент: друга от тези рамки препоръчва подготовката да се декларира като проект, от който зависят останалите, вместо чрез глобалната ѝ функция, защото така се интегрира по-добре с нейния изпълнител на тестове [4].
И подготвеното не е непременно достъпно по един и същи начин за всеки тест: една от тези рамки уточнява, че глобалните променливи, дефинирани в подготовката ѝ, не могат да се четат от тестовете [5]. Екипът ви трябва да провери това, преди да приеме поправката за завършена.
Правило 2. Пакетът от тестове има бюджет и се сравнява версия срещу версия
Както един проект има бюджет в пари, етапът на тестовете има бюджет за продължителност и той се следи при всяка версия.
Не стига да «се побира в лимита». Въпросът е дали отнема същото време като предишната версия и, ако отнема повече, дали някой го е очаквал. За това веригата за доставка има контролна бариера: автоматично правило, което спира пускането, когато продължителността надхвърли допустимото отклонение. Например, ако етапът е отнемал 12 минути, а новата версия отнема 16, без някой да го е предвидил, това се вижда и се обяснява, преди да се продължи.
Това е бариера, а не статистика, която някой преглежда, когато се сети. С нея този екип щеше да може да открие отклонението през седмица 2, а не през седмица 5, когато струваше една кампания. Това е указанието на Fowler да се действа веднага щом build-ът започне да надхвърля [1], превърнато в автоматичен контрол.
Правило 3. Вдигането на лимита или разделянето на тестове не се брои за поправка
Когато пакетът от тестове се удари в бюджета си, първият въпрос не е «с колко още време да му дадем?», а «какво се повтаря, без да трябва?».
Вдигането на лимита може да е валидна временна мярка за спешно пускане, но се записва като това, което е — дълг със срок и с отговорник — и разследването на причината се открива още същия ден. Ако лимитът се вдигне и никой не открие разследване, това не е било техническо решение: било е замитане под килима.
| Ситуация | Слаб отговор | Отговор, който това правило изисква |
|---|---|---|
| Build-ът наближава лимита | Вдигане на лимита | Да се измери къде отива времето: подготовка срещу тестване |
| Някои файлове са бавни | Разделянето им | Да се провери дали всяко парче повтаря фиксирана цена |
| Машината се претоварва | Намаляване на паралелизма и паметта | Да се измери преди и след; ако продължителността се увеличи — връщане назад |
| Има непостоянни тестове | Повече време за тях | Да се третират като аларма с отговорник и причина |
Каква роля изигра изкуственият интелект?
Никаква, която да го прави виновен или невинен: предложенията отговаряха на въпроса, който екипът задаваше, а въпросът за причината никой не зададе.
Обвиняването на инструмента или оправдаването му не помага на ръководството. Въпросът, който екипът задаваше, беше «как да го накарам да мине?», и предложенията, които получи, отговаряха на това: повече време, повече парчета, по-малко процеси. Правдоподобни отговори на грешния въпрос.
Проблемът беше друг: екипът прие всяка кръпка, без да пита защо. Когато човек с малко опит предложи да се вдигне времеви лимит, някой с повече опит обикновено го пита «а защо отнема толкова?». Когато предложението пристига мигновено и е написано уверено, този въпрос се прескача по-лесно.
Скоростта на асистентите не премахва нуждата от преценка: увеличава я, защото сега и грешките се произвеждат по-бързо. Правилото, което оставя тази история, е лесно за писане и взискателно за спазване: кръпка, която не обяснява причината, не се приема, независимо дали идва от човек, или от инструмент. Прегледът на промените изисква доказателства за причината, за очакваното въздействие и за последващото измерване, независимо откъде идва предложението.
Как изглежда скучната версия на тази история?
Това е същата седмица 2, с бариера, която вдига тревога навреме, и с някой, който пита защо.
В тази версия във вторника на седмица 2 бариерата отчита, че етапът е минал от 12 на 16 минути без обяснение. Версията се задържа за няколко часа. Човек от екипа измерва къде отива времето и открива, че почти всичко е подготовка: всеки файл изгражда сайта от нулата.
Същия следобед сайтът се изгражда веднъж в началото и всички тестове го използват; примерната база данни се нулира по контролиран начин между тестовете. След като промяната бъде потвърдена, етапът може да се върне в договорения бюджет, а лимитът остава там, където беше.
Три седмици по-късно, в петъка на кампанията, друг конвейер заема същата машина и build-ът отнема малко повече. С достатъчен резерв за това допълнително натоварване рискът пакетът от тестове да спре пускането е много по-малък.
Това е скучната версия. А във веригата за доставка скучното е целта.
Ключови изводи
Четири въпроса за следващия ви технологичен комитет:
- Колко продължава днес етапът на тестовете на основните ни системи, колко продължаваше преди три месеца и кой следи тази разлика?
- Колко пъти тази година сме вдигали времеви лимит и в колко от тези случаи е било открито разследване на причината, със срок и отговорник?
- Знаем ли каква част от продължителността на тестовете ни е подготовка и каква част е тестване?
- Когато асистент с изкуствен интелект предложи кръпка, нашият процес на преглед изисква ли от него да обясни причината, или само пускането да мине?
Какво прави Hábil?
Hábil помага веригата ви за доставка да е бърза и надеждна, така че пускането на промяна да престане да бъде залагане.
Пакет от тестове с растяща продължителност може да забави пусканията и да създаде оперативни разходи, които никой не вижда да идват. Работим с вашия екип в четири направления:
- Тестове, които измерват важното. Всеки тест да проверява нещо от бизнеса, а скъпото да се подготвя веднъж, не двеста и трийсет пъти.
- Следен бюджет за продължителност. Продължителността на тестовете се контролира като всеки друг бюджет, с бариера, която я сравнява версия срещу версия.
- Всяка аларма с отговорник и причина. Непостоянните тестове и времевите лимити се третират като предупреждения, които се разследват, а не като шум, който се заглушава.
- ИИ асистенти, без да се губи преценката. Екипът ви използва скоростта на асистентите с преглед, който изисква всяка промяна да обяснява своето защо.
Вграждаме тестовете и сигурността в пътя на доставката. Вижте Облак и DevSecOps.
Ако етапът на тестовете ви расте от седмици и вече сте вдигали лимита повече от веднъж, да започнем оттам. Да обсъдим вашия проект. Първият разговор е без заплащане.
Често задавани въпроси
Грешно ли е да се вдига времевият лимит на build-а?
Не непременно. Може да е валидна временна мярка, за да излезе спешно пускане. Проблемът се появява, когато се използва като поправка: ако лимитът се вдигне и никой не измери къде отива времето, причината продължава да расте. Затова всяко увеличение се записва като дълг със срок и отговорник.
Как да разбера дали екипът ми има същия дефект?
Ясен признак е този от седмица 5: продължителността расте много повече от броя на тестовете. Друг — разделянето на бавните файлове не подобрява общото време. Същинската проверка е да се измери за всеки файл колко отива за подготовка на средата и колко за тестване. Ако подготовката преобладава и се повтаря във всеки файл, там е цената.
Източниците са проверени на 6 ноември 2026 г. Цитатите от документи на английски са преведени.
Източници
- Martin Fowler, «Continuous Integration», martinfowler.com. https://martinfowler.com/articles/continuousIntegration.html
- DORA, «Capabilities: Continuous integration», dora.dev. https://dora.dev/capabilities/continuous-integration/
- John Micco, «Flaky Tests at Google and How We Mitigate Them», Google Testing Blog, 27 май 2016 г. https://testing.googleblog.com/2016/05/flaky-tests-at-google-and-how-we.html
- Playwright, «Global setup and teardown», официална документация. https://playwright.dev/docs/test-global-setup-teardown
- Jest, «Configuring Jest: globalSetup [string]», официална документация. https://jestjs.io/docs/configuration#globalsetup-string
- pytest, «How to use fixtures: Fixture scopes», официална документация. https://docs.pytest.org/en/stable/how-to/fixtures.html
Dorian Chávez разказва версия на този модел, на испански, в своя Substack «En construcción»: https://enconstruccionmx.substack.com/p/la-suite-que-se-comio-la-entrega
- Облак и инфраструктура →
- Пускайте версии без страх в собствената си инфраструктура →
- Тестове, които хващат грешки →
Вашата дейност среща ли тези предизвикателства?
Предпочитате имейл? Пишете ни на hola@habil.mx