Защо
През последния месец описание на PR четири пъти твърдеше, че нещо е покрито, а мутация показваше обратното:
| PR |
твърдението |
какво показа мутацията |
| #283 |
„свързването е покрито" |
връщане към една заявка на таблица - 19 минават, 0 падат |
| #283 |
runShip затваря дупката |
заобикаляне на runShip в main() - зелено |
| #283 |
тестът през край покрива пътя |
пращане на всичко към производствен слот - зелено |
| #270 |
пазачът пази корпуса |
пазачът питаше за contracts, а изчистването бърше 14 таблици |
И четирите са уловени на ръка, след като описанието вече е било публикувано като вярно. Процентното покритие беше зелено през цялото време. Тоест единственото, което ги хвана, беше някой, който реши да провери.
Твърдение в описание не е проверка. Никой не го пуска пак при следващата промяна.
Какво предлагам, в две стъпки
Стъпка 1 - записаните мутации (евтината, започваме с нея). Малък списък от конкретни мутации като кръпки под test/mutations/, и лента в CI, която за всяка проверява, че наборът става червен. Не открива нови дупки; заковава точно гаранциите, които вече изтървахме. Дни работа, без инструментална дупка.
Началният списък е готов - това са мутациите от таблицата горе плюс тези от #270:
- рушащият път се връща към една заявка на таблица;
- редът със сверката се маха;
- пазачът пита само за
contracts;
- знакът
@full-clear се маха от normalize-raw.sql;
- отказът „не мога да прочета" се маха;
- пазачът се мести след зареждането.
Стъпка 2 - истинско мутационно изпитване, ако стъпка 1 се окаже недостатъчна. Тясно, само върху файловете, чийто провал е тих и скъп: scripts/ship-related-persons.mjs, scripts/import.mjs, packages/ingest/src/refresh.ts и fx.ts, packages/db/src/readonly-*.ts. Не върху целия монорепо - там връща предимно шум.
Пречки за стъпка 2, заради които не започваме от нея: за плоските .mjs под scripts/ няма удобен инструмент (за TS има Stryker), а наборът на scripts/ е около 25 секунди и мутациите го умножават. Прагът трябва да е доклад, преди да стане гейт - иначе първият червен гейт ще бъде изключен.
Границата, която трябва да е записана в issue-то
Мутациите не хващат всичко. Пример от същата седмица (#293): подставеният wrangler в теста печаташе известие на stdout, а истинският го пише на stderr. Кодът и тестът бяха вързани коректно - сгрешен беше моделът на инструмента. Наборът беше зелен и невярното твърдение стигна до описанието на PR-а и до коментар в кода.
Затова към същата работа върви и второ, по-скучно правило: подставен инструмент се сверява веднъж срещу истинския и това се записва в теста. Каквото не е проверено срещу истинския двоичен файл, се обозначава като хипотеза.
Приемане
- лента в CI, която пуска записаните мутации и вали, ако някоя от тях не прави набора червен;
- шестте мутации по-горе са в списъка;
docs/review-testing.md описва как се добавя мутация и защо списъкът е точно този;
- правилото за подставките е записано там.
Защо
През последния месец описание на PR четири пъти твърдеше, че нещо е покрито, а мутация показваше обратното:
runShipзатваря дупкатаrunShipвmain()- зеленоcontracts, а изчистването бърше 14 таблициИ четирите са уловени на ръка, след като описанието вече е било публикувано като вярно. Процентното покритие беше зелено през цялото време. Тоест единственото, което ги хвана, беше някой, който реши да провери.
Твърдение в описание не е проверка. Никой не го пуска пак при следващата промяна.
Какво предлагам, в две стъпки
Стъпка 1 - записаните мутации (евтината, започваме с нея). Малък списък от конкретни мутации като кръпки под
test/mutations/, и лента в CI, която за всяка проверява, че наборът става червен. Не открива нови дупки; заковава точно гаранциите, които вече изтървахме. Дни работа, без инструментална дупка.Началният списък е готов - това са мутациите от таблицата горе плюс тези от #270:
contracts;@full-clearсе маха отnormalize-raw.sql;Стъпка 2 - истинско мутационно изпитване, ако стъпка 1 се окаже недостатъчна. Тясно, само върху файловете, чийто провал е тих и скъп:
scripts/ship-related-persons.mjs,scripts/import.mjs,packages/ingest/src/refresh.tsиfx.ts,packages/db/src/readonly-*.ts. Не върху целия монорепо - там връща предимно шум.Пречки за стъпка 2, заради които не започваме от нея: за плоските
.mjsподscripts/няма удобен инструмент (за TS има Stryker), а наборът наscripts/е около 25 секунди и мутациите го умножават. Прагът трябва да е доклад, преди да стане гейт - иначе първият червен гейт ще бъде изключен.Границата, която трябва да е записана в issue-то
Мутациите не хващат всичко. Пример от същата седмица (#293): подставеният
wranglerв теста печаташе известие на stdout, а истинският го пише на stderr. Кодът и тестът бяха вързани коректно - сгрешен беше моделът на инструмента. Наборът беше зелен и невярното твърдение стигна до описанието на PR-а и до коментар в кода.Затова към същата работа върви и второ, по-скучно правило: подставен инструмент се сверява веднъж срещу истинския и това се записва в теста. Каквото не е проверено срещу истинския двоичен файл, се обозначава като хипотеза.
Приемане
docs/review-testing.mdописва как се добавя мутация и защо списъкът е точно този;