Preskočiť na obsah

Red-green TDD s AI agentom: test musí najprv padnúť

Pre CTO a vývojárovHarness a kontroly · Aktualizované

Filip Papraneczakladateľ Digitaliko

Test, ktorý prejde na starom kóde, nič nedokazuje. Ilustrácia: ten istý test spustený dvakrát, červený na základnej vetve a zelený na vetve so zmenou.Test, ktorý prejde na starom kóde, nič nedokazuje. Ilustrácia: ten istý test spustený dvakrát, červený na základnej vetve a zelený na vetve so zmenou.

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:

  1. Red. Nový test musí padnúť na základnej vetve, teda na kóde pred zmenou.
  2. Green. Ten istý test musí prejsť na vetve so zmenou.
  3. Bez testu žiadna zmena. Zmenený zdrojový kód bez zmeneného testu je zlyhanie.
Red-proof na príklade testu „zľava sa uplatní iba raz“: agent commitne iba test, na základnej vetve main test padne (FAIL), na vetve so zmenou prejde (PASS). Ak by prešiel aj na main, PR je červený.Red-proof na príklade testu „zľava sa uplatní iba raz“: agent commitne iba test, na základnej vetve main test padne (FAIL), na vetve so zmenou prejde (PASS). Ak by prešiel aj na main, PR je červený.

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.

scoped=""
(cd "$W/base" && sh -c "$cmd") > "$W/base-test.log" 2>&1 || scoped=" $(echo $tests)"

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:

ZmenaRed-proofKto 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 testuZlyhanie, PR je červený.Brána
Čistý refaktoring alebo konfiguráciaMôže byť výnimka: label skip-red-proof v našom verejnom starteri.Človek, nikdy agent
Viditeľná zmena v UIK 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
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:

  1. Najprv test

    Agent napíše jeden test na najrizikovejšie kritérium a commitne ho samostatne.

  2. Brána lokálne

    Pred „hotovo“ pustí gate.sh proti origin/main.

  3. Job v CI

    Samostatný job red-proof na každom pull requeste.

  4. 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.

Pravidlá ako „test musí najprv padnúť“ patria do repozitára, nie do hlavy seniora. Viac v článku Pravidlá pre AI kód v tíme. Prečo sú kontroly okolo modelu dôležitejšie než model, je v článku Harness engineering v praxi: AI agent od issue po PR.

Chcete testy od AI, ktoré niečo dokážu?

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é.

Ak sa chcete najprv porozprávať, dohodnite si meeting na 15 minút s Filipom.

Ktoré z vašich testov by prešli, aj keby ste funkciu zmazali?

V skratke

  • Test, ktorý prejde pred zmenou aj po nej, zmenu nedokazuje.
  • Red-proof: nový test musí padnúť na základnej vetve a prejsť na vetve so zmenou.
  • Kontroluje to skript v CI, nie disciplína. Výnimku dáva iba človek.
  • Keď main už padá, pustite nové testovacie súbory samostatne. Nepresvedčivé je zlyhanie.

Časté otázky

Čo je red green refactor?

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.

ChatGPTClaudePerplexity
Engineering

Ostatné články

Harness a kontroly

Playwright MCP: AI agent overí zmenu v prehliadači

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.

Harness a kontroly

LLM as a judge: AI recenzent, ktorý sa snaží prácu vyvrátiť

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.

Harness a kontroly

AI code review s Claude Code v CI: čo AI prehliadne

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.

Čas prestať plánovať a začať riešiť.

Kontakt

  • Digitaliko s.r.o.
    Šípková 377/17
    958 03 Malé Uherce, Slovensko
  • Ozvite sa nám
    info@digitaliko.com
    +421 950 595 506
    WhatsApp