chimera-prove-the-test-discriminates
Un test di regressione che non hai mai visto fallire è una supposizione. Rompi di nuovo il codice e guardalo diventare rosso prima di farne commit.
Conferita da chi ha letto la scheda, non rivendicata dal file su se stesso. Una scheda che l'agente distilla durante un'esecuzione che ha consumato contenuti non affidabili nasce contaminata e resta in attesa di revisione prima di essere mai recuperata.
Quando viene in mente
- ho scritto un test di regressione
- ho corretto un bug e aggiunto un test
- il test passa, rilasciamo
- aggiungo un test dopo il fix
Il valore di solito sta in Evita e Verifica. Fai è la sezione che scrivono tutti.
Il corpo della scheda qui sopra è una traduzione. L'originale inglese è ciò che la CLI importa, ciò che l'agente legge in esecuzione e ciò che l'hash qui sotto attesta.
Trigger
Hai corretto un bug e scritto un test perché non possa tornare. Il test passa. È tutta la prova che hai, ed è la stessa prova che avresti se il test non verificasse assolutamente nulla riguardo al bug.
Vale soprattutto quando il test è stato scritto dopo la correzione, perché allora l'unico codice contro cui il test sia mai stato eseguito è codice in cui il bug è già sparito. Vale meno per un test scritto prima, rosso, in un ciclo TDD — quello l'hai già visto fallire, che è l'intero senso del ciclo.
Non si applica a un test per un comportamento genuinamente nuovo, dove non c'è un "prima" a cui tornare. Lì il controllo discriminante è diverso: cancella la nuova implementazione e conferma che il test fallisca sull'assenza, non sul bug.
Fai
- Individua la modifica esatta che costituisce la correzione — l'hunk, non il commit. Se la correzione è un solo confronto cambiato, è quel confronto che andrai ad annullare.
- Annullala. Fai
git stashdella correzione, oppure riporta a mano quell'unica riga alla sua forma rotta. - Esegui solo il test nuovo:
pytest tests/test_thing.py::test_the_regression -x. - Leggi il fallimento. Deve essere la tua asserzione a fallire, con un messaggio che parla del
comportamento — non un
SyntaxError, non un errore di collection, non unImportErrorche viene da un file annullato a metà. Quelli sono rossi per il motivo sbagliato e non provano nulla sul test. - Ripristina la correzione (
git stash pop) e conferma che lo stesso test ora passa. - Metti il fatto nella docstring del test: cosa è stato annullato, e che aspetto aveva il fallimento. La prossima persona che tocca questo test ha bisogno di sapere che è stato davvero esercitato contro il bug.
Evita
Verificare qualcosa che è vero in entrambi i mondi. La forma classica:
result = parse_config(raw)
assert result is not None
assert "timeout" in result
Il bug era che timeout tornava come stringa "30" invece che come int 30. Entrambe le asserzioni
reggono in un caso e nell'altro. Ciò che discrimina è la cosa che è cambiata:
# RIGHT — fails against the buggy code
assert parse_config(raw)["timeout"] == 30
assert isinstance(parse_config(raw)["timeout"], int)
Evita anche di annullare la correzione commentando un'intera funzione o cancellando un import per "farlo fallire in fretta". Questo produce un'esecuzione rossa che sarebbe avvenuta per qualsiasi test del file, quindi non ti dice nulla su questo. L'annullamento deve essere la correzione e solo la correzione.
Ed evita il quasi-errore in cui il test raggiunge il codice corretto attraverso un percorso che la
produzione non usa mai — quello è un fallimento diverso, e la card che lo riguarda è
chimera-test-the-wiring-not-the-class.
Verifica
Una domanda binaria: hai visto personalmente questo test stampare un fallimento causato dalla sua stessa asserzione, contro il codice non corretto?
Se sì, hai finito. Se la risposta è "sarebbe fallito", non hai verificato nulla — quella frase è una previsione prodotta dallo stesso ragionamento che ha scritto il test.
Meccanicamente:
git stash # remove the fix
pytest tests/test_x.py::test_regression # MUST be red, on your assertion
git stash pop # restore
pytest tests/test_x.py::test_regression # MUST be green
Rosso e poi verde, osservati entrambi, altrimenti il test non è dimostrato.
Rischio
Alcune correzioni non si annullano a basso costo: l'aggiornamento di una dipendenza, una migrazione di schema, un file cancellato, una modifica dentro una libreria vendorizzata. Forzare un annullamento lì può costare più di quanto valga il test. Il ripiego onesto è ricostruire l'input che prima lo rompeva e verificare il valore specifico, poi dire chiaramente nella docstring che l'esecuzione rossa non è stata osservata — un test non dimostrato che ammette di non esserlo è molto meglio di uno che lascia intendere di essere stato verificato.
Il vero pericolo di questa card è l'annullamento che dimentichi di annullare. Fare questa danza in un
working tree sporco è il modo in cui una riga di nuovo rotta finisce in commit accanto al proprio
test di regressione, con la suite verde perché hai ripristinato la correzione nel file sbagliato.
Esegui git diff prima di fare commit, ogni volta.
E un test discriminante vale comunque solo quanto il bug che hai capito. Dimostra che il test cattura questa regressione. Non dimostra che tu abbia corretto la causa radice invece del sintomo, e trattare un'esecuzione rosso-poi-verde come prova di questo è una tesi più grande di quanto la prova sostenga.
Come usarla
La scheda è un dato. Clona il repository e importala per percorso — ciò che arriva dalla rete è trattato come contaminato e trattenuto in attesa di approvazione, che è il comportamento desiderabile e il motivo per cui qui non c'è un installatore in una riga.
git clone https://github.com/brcampidelli/chimera-agent.gitchimera skills-import chimera-agent/skills/chimera-prove-the-test-discriminates/SKILL.mdIntegrità
SHA-256 del file così com'è pubblicato. Chi lo importa può verificare che ciò che ha ricevuto sia ciò che questa pagina mostrava.
90d4bf00eb67055008527ee372153b2637fa2feea601ed6760997eda239f0b76