AI agenti píšu testy, ktoré prejdú. To nie sú testy, ktoré niečo dokážu, a senior, ktorý ich má v review rozlíšiť, stratí čas, ktorý mala AI ušetriť. Preto naša brána pustí každý nový test najprv na starom kóde. Ak prejde aj tam, PR je červený.
Je to red-green-refactor, ktorý vynucuje stroj, nie disciplína. AI dnes píše všetok náš kód a za výsledok ručí senior. Red-proof je spôsob, ako môže ten senior veriť zelenej kontrole.
Prečo sú testy od AI riziko?
Poproste agenta, nech „pridá testy“, a dostanete testy, ktoré svietia na zeleno. Ak mu nepoviete inak, píše ich po kóde a podľa kódu, takže potvrdzujú to, čo kód už robí. Niektoré kód ani nezavolajú. Videli sme testy, ktoré čítali zdrojový súbor ako text a hľadali v ňom názov funkcie. Prejdú na akejkoľvek verzii, v ktorej to slovo je.
Pokrytie stúpne. Dôkaz ostane tam, kde bol. Posledná obrana je recenzent a dôkladne čítať každý test je presne práca, ktorej ste sa chceli zbaviť.
Ako je na tom váš tím?
Čo je red-proof?
Červený krok z red-green-refactor, ktorý kontroluje skript:
Red. Nový test musí padnúť na základnej vetve, teda na kóde pred zmenou.
Green. Ten istý test musí prejsť na vetve so zmenou.
Bez testu žiadna zmena. Zmenený zdrojový kód bez zmeneného testu je zlyhanie.
Zadanie, ktoré náš agent dostane pri úlohách s kódom, hovorí to isté slovami. Napíš jeden test na najrizikovejšie kritérium a commitni ho samostatne. Na nezmenenom kóde musí padnúť. Potom implementuj. Test po jeho commite neupravuj.
Slová sú prosba. Brána je zámok.
Ako to brána kontroluje?
Je to obyčajný bash, gate.sh v harnesse nášho agenta. Jadro, skrátené:
# red-proof: the branch's new/changed tests must FAIL on the base code, or they prove nothing
changed=$(git diff --name-only "$base"...HEAD; git ls-files --others --exclude-standard)
tests=$(printf '%s\n' "$changed" | grep -E '(^|/)(tests?|__tests__|spec)/|\.(test|spec)\.[a-z]+$')
src=$(printf '%s\n' "$changed" | grep -E '\.(ts|tsx|js|jsx|mjs|py|go|rs|php|rb)$' \
| grep -vE '(^|/)(tests?|__tests__|spec)/|\.(test|spec)\.')
if [ -z "$tests" ]; then
[ -n "$src" ] && echo "FAIL red-proof: source changed but no test was added or changed"
else
cmd=$(jq -r .scripts.test package.json)
git worktree add -q --detach "$W/base" "$base" # the old code, next to the branch
for t in $tests; do cp "$t" "$W/base/$t"; done # the new tests, onto the old code
if (cd "$W/base" && sh -c "$cmd") > "$W/red-test.log" 2>&1; then
echo "FAIL red-proof: the new tests also pass on $base, so they do not prove the change"
else
echo "PASS red-proof: new tests fail on $base and pass on the branch"
fi
fi
Okolo sú tri pravidlá:
Testy bez skriptu test sú zlyhanie. Nič by ich nespustilo.
Recenzent číta, prečo testy na základnej vetve padli. Brána vypíše prvé asercie z červeného behu. Pád pre chýbajúci súbor alebo import nie je červený dôkaz a recenzent to povie.
Testy, ktoré čítajú zdrojový kód ako text, idú späť. Pokyny recenzenta ich menujú: test musí zavolať funkciu, vykresliť komponent alebo poslať požiadavku na route.
Brána neznamená, že testov má byť čo najviac. Zbytočné testy mažeme. Niekedy treba zjednodušiť, nie iba pridávať.
Čo sa pokazilo: falošný PASS na červenej main
Prvá verzia mala dieru. Keď základná vetva už padala na vlastných testoch, každý nový test tam vyzeral červený. Brána hlásila PASS pre testy, ktoré nič nedokazovali.
Oprava: ak sada na základnej vetve už padá, pustia sa iba nové testovacie súbory samostatne. Na základnej vetve musia padnúť, na vetve so zmenou prejsť. Ak sa samostatne spustiť nedajú, výsledok je nepresvedčivý, a nepresvedčivý znamená zlyhanie.
Druhou dierou bolo prostredie. Na jednom našom projekte red-proof spúšťal testy bez správneho prostredia: chýbal nástroj (turbo: command not found) a bežala iná verzia Node. Testy na základnej vetve padli skôr, než sa vôbec spustili. Brána to brala ako červený dôkaz, takže každý red-proof tam bol falošný PASS.
Tá istá oprava sprísnila screenshoty. Viditeľná zmena v UI predtým prešla s akýmkoľvek priloženým PNG. Dnes potrebuje snímku pred aj po.
Potrebuje každá zmena červený test?
Nie. Čistý refaktoring alebo zmena konfigurácie nemá čo nové dokazovať. Všetko ostatné ide cez bránu:
Zmena
Red-proof
Kto rozhoduje
Nová funkcia alebo oprava chyby
Áno. Nový test padne na základnej vetve a prejde na vetve so zmenou.
Brána
Zmena zdrojového kódu bez testu
Zlyhanie, PR je červený.
Brána
Čistý refaktoring alebo konfigurácia
Môže byť výnimka: label skip-red-proof v našom verejnom starteri.
Človek, nikdy agent
Viditeľná zmena v UI
K testu ešte snímka pred aj po.
Brána a recenzent
Pri kritickom softvéri, ktorý počíta ceny alebo rozhoduje o ľuďoch, platí opak. Tam bránu nevypíname.
Je rozdiel, či píšete appku navibecodenú len tak, alebo kritickú vec. Aj keď kód píše agent, tam potrebujete testy a všetky brány.
Filip Papranec
zakladateľ Digitaliko
Ako pridať red-proof do vášho CI?
Rovnaká brána je v našom verejnom Claude Code production starteri, licencia MIT. Pustite ju lokálne skôr, než poviete „hotovo“:
bash scripts/gate.sh all origin/main
Postup, ktorý odporúčame:
01
Najprv test
Agent napíše jeden test na najrizikovejšie kritérium a commitne ho samostatne.
02
Brána lokálne
Pred „hotovo“ pustí gate.sh proti origin/main.
03
Job v CI
Samostatný job red-proof na každom pull requeste.
04
Výnimky dáva človek
Label skip-red-proof iba pre čistý refaktoring alebo konfiguráciu.
Starter má jednoduchšiu verziu bez samostatného behu nových súborov, takže hlavnú vetvu držte zelenú. To je dobrá rada aj tak.
Takéto brány nastavujeme priamo v repozitári tímu v rámci služby AI-native SDLC pre vývojové tímy. Chýbajú vášmu tímu skôr ruky než pravidlá? Pozrite si seniorského vývojára do tímu. Od roku 2023 sme dodali 15+ produkčných projektov. Senior sa pripojí do vášho repozitára a pull requestov od prvého týždňa.
Ozveme sa do dvoch pracovných dní a spolu vyberieme, čo vyriešime ako prvé.
Cyklus vývoja riadeného testami: napíšete test, ktorý padne (red), kód, s ktorým prejde (green), a potom upracete (refactor). Červený krok dokazuje, že test overuje nové správanie.
Ako robiť vývoj riadený testami s AI agentom?
Nech agent najprv napíše jeden test a commitne ho samostatne, až potom implementuje. Vynúťte to v CI: nový test musí padnúť na základnej vetve a prejsť na vetve so zmenou. Inak je PR červený.
Prečo musí nový test padnúť na základnej vetve?
Test, ktorý prejde pred zmenou aj po nej, zmenu netestuje. Možno netestuje nič, alebo iba správanie, ktoré už existovalo.
Čo ak už hlavná vetva má padajúce testy?
Potom padá celá sada na základnej vetve a každý nový test vyzerá červený. Pustite iba nové testovacie súbory samostatne. Ak sa samostatne spustiť nedajú, berte výsledok ako zlyhanie, nie ako úspech.
Môže agent red-proof preskočiť?
Sám nie. Čistý refaktoring alebo zmena konfigurácie môžu byť výnimkou, ale rozhoduje o tom človek, labelom na pull requeste.
Opýtajte sa AI na tento článok
AI pri odpovedi využije aj naše ďalšie články a skúsenosti z reálnych projektov.
Playwright MCP dáva AI agentovi skutočný prehliadač. Ako ho používame, aby agent overil svoju zmenu v bežiacej aplikácii a vrátil PASS alebo FAIL so screenshotmi, čo tým chytíme oproti unit testom a kedy sú lepšie obyčajné Playwright skripty.
LLM as a judge znamená, že jazykový model hodnotí prácu iného modelu podľa spísaných kritérií. Ako ho používame na každom pull requeste nášho AI agenta: najprv strojové kontroly, potom čerstvá session len na čítanie, ktorá má prácu vyvrátiť, typovaný verdikt a pravidlá, ktoré pribudli po jeho chybách.
Ako robíme AI code review s Claude Code na každom pull requeste jednou zdieľanou GitHub Action: čo má AI recenzent hľadať, ako bolo zelené a mlčalo, čo prehliadne a prečo schvaľuje len človek.