AI agenti píšou testy, které projdou. To nejsou testy, které něco dokážou, a senior, který je má v review rozlišit, ztratí čas, který měla AI ušetřit. Proto naše brána pustí každý nový test nejdřív na starém kódu. Pokud projde i tam, PR je červený.
Je to red-green-refactor, který vynucuje stroj, ne disciplína. AI dnes píše veškerý náš kód a za výsledek ručí senior. Red-proof je způsob, jak může ten senior věřit zelené kontrole.
Proč jsou testy od AI riziko?
Požádejte agenta, ať „přidá testy“, a dostanete testy, které svítí zeleně. Když mu neřeknete jinak, píše je po kódu a podle kódu, takže potvrzují to, co kód už dělá. Některé kód ani nezavolají. Viděli jsme testy, které četly zdrojový soubor jako text a hledaly v něm název funkce. Projdou na jakékoli verzi, ve které to slovo je.
Pokrytí stoupne. Důkaz zůstane tam, kde byl. Poslední obranou je recenzent a pečlivě číst každý test je přesně práce, které jste se chtěli zbavit.
Jak je na tom váš tým?
Co je red-proof?
Červený krok z red-green-refactor, který kontroluje skript:
Red. Nový test musí selhat na základní větvi, tedy na kódu před změnou.
Green. Stejný test musí projít na větvi se změnou.
Bez testu žádná změna. Změněný zdrojový kód bez změněného testu je selhání.
Zadání, které náš agent dostane u úloh s kódem, říká totéž slovy. Napiš jeden test na nejrizikovější kritérium a commitni ho samostatně. Na nezměněném kódu musí selhat. Pak implementuj. Test po jeho commitu neupravuj.
Slova jsou prosba. Brána je zámek.
Jak to brána kontroluje?
Je to obyčejný bash, gate.sh v harnessu našeho agenta. Jádro, zkráceně:
# 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
Kolem jsou tři pravidla:
Testy bez skriptu test jsou selhání. Nic by je nespustilo.
Recenzent čte, proč testy na základní větvi selhaly. Brána vypíše první aserce z červeného běhu. Pád kvůli chybějícímu souboru nebo importu není červený důkaz a recenzent to řekne.
Testy, které čtou zdrojový kód jako text, jdou zpět. Pokyny recenzenta je jmenují: test musí zavolat funkci, vyrenderovat komponentu nebo poslat požadavek na route.
Brána neznamená, že testů má být co nejvíc. Zbytečné testy mažeme. Někdy je potřeba zjednodušit, ne jen přidávat.
Co se rozbilo: falešný PASS na červené main
První verze měla díru. Když základní větev už padala na vlastních testech, každý nový test tam vypadal červeně. Brána hlásila PASS pro testy, které nic nedokazovaly.
Oprava: pokud sada na základní větvi už padá, pustí se jen nové testovací soubory samostatně. Na základní větvi musí selhat, na větvi se změnou projít. Pokud se samostatně spustit nedají, výsledek je nepřesvědčivý, a nepřesvědčivý znamená selhání.
Druhou dírou bylo prostředí. Na jednom našem projektu red-proof spouštěl testy bez správného prostředí: chyběl nástroj (turbo: command not found) a běžela jiná verze Node. Testy na základní větvi selhaly dřív, než se vůbec spustily. Brána to brala jako červený důkaz, takže každý red-proof tam byl falešný PASS.
Stejná oprava zpřísnila screenshoty. Viditelná změna v UI dřív prošla s jakýmkoli přiloženým PNG. Dnes potřebuje snímek před i po.
Potřebuje každá změna červený test?
Ne. Čistý refaktoring nebo změna konfigurace nemá co nového dokazovat. Všechno ostatní jde přes bránu:
Změna
Red-proof
Kdo rozhoduje
Nová funkce nebo oprava chyby
Ano. Nový test selže na základní větvi a projde na větvi se změnou.
Brána
Změna zdrojového kódu bez testu
Selhání, PR je červený.
Brána
Čistý refaktoring nebo konfigurace
Může být výjimka: label skip-red-proof v našem veřejném starteru.
Člověk, nikdy agent
Viditelná změna v UI
K testu ještě snímek před i po.
Brána a recenzent
Opačně to platí u kritického softwaru, který počítá ceny nebo rozhoduje o lidech. Tam bránu nevypínáme.
Je rozdíl, jestli píšete appku navibecoděnou jen tak, nebo kritickou věc. I když kód píše agent, tam potřebujete testy a všechny brány.
Filip Papranec
zakladatel Digitaliko
Jak přidat red-proof do vašeho CI?
Stejná brána je v našem veřejném Claude Code production starteru, licence MIT. Pusťte ji lokálně dřív, než řeknete „hotovo“:
bash scripts/gate.sh all origin/main
Postup, který doporučujeme:
01
Nejdřív test
Agent napíše jeden test na nejrizikovější kritérium a commitne ho samostatně.
02
Brána lokálně
Před „hotovo“ pustí gate.sh proti origin/main.
03
Job v CI
Samostatný job red-proof na každém pull requestu.
04
Výjimky dává člověk
Label skip-red-proof jen pro čistý refaktoring nebo konfiguraci.
Starter má jednodušší verzi bez samostatného běhu nových souborů, takže hlavní větev držte zelenou. To je dobrá rada tak jako tak.
Takové brány nastavujeme přímo v repozitáři týmu v rámci služby AI-native SDLC pro vývojové týmy. Chybí vašemu týmu spíš ruce než pravidla? Podívejte se na seniorního vývojáře do týmu. Od roku 2023 jsme dodali 15+ produkčních projektů. Senior se připojí do vašeho repozitáře a pull requestů hned první den.
Ozveme se do dvou pracovních dnů a společně vybereme, co vyřešíme jako první.
Cyklus vývoje řízeného testy: napíšete test, který selže (red), kód, se kterým projde (green), a pak uklidíte (refactor). Červený krok dokazuje, že test ověřuje nové chování.
Jak dělat vývoj řízený testy s AI agentem?
Ať agent nejdřív napíše jeden test a commitne ho samostatně, teprve potom implementuje. Vynuťte to v CI: nový test musí selhat na základní větvi a projít na větvi se změnou. Jinak je PR červený.
Proč musí nový test selhat na základní větvi?
Test, který projde před změnou i po ní, změnu netestuje. Možná netestuje nic, nebo jen chování, které už existovalo.
Co když už hlavní větev má padající testy?
Pak padá celá sada na základní větvi a každý nový test vypadá červeně. Pusťte jen nové testovací soubory samostatně. Pokud se samostatně spustit nedají, berte výsledek jako selhání, ne jako úspěch.
Může agent red-proof přeskočit?
Sám ne. Čistý refaktoring nebo změna konfigurace mohou být výjimkou, ale rozhoduje o tom člověk, labelem na pull requestu.
Zeptejte se AI na tento článek
AI při odpovědi využije i naše další články a zkušenosti z reálných projektů.
Playwright MCP dává AI agentovi skutečný prohlížeč. Jak ho používáme, aby agent ověřil svou změnu v běžící aplikaci a vrátil PASS nebo FAIL se screenshoty, co tím chytíme oproti unit testům a kdy jsou lepší obyčejné Playwright skripty.
LLM as a judge znamená, že jazykový model hodnotí práci jiného modelu podle sepsaných kritérií. Jak ho používáme na každém pull requestu našeho AI agenta: nejdřív strojové kontroly, pak čerstvá session jen pro čtení, která má práci vyvrátit, typovaný verdikt a pravidla, která přibyla po jeho chybách.
Jak děláme AI code review s Claude Code na každém pull requestu jednou sdílenou GitHub Action: co má AI recenzent hledat, jak bylo zelené a mlčelo, co přehlédne a proč schvaluje jen člověk.