chimera-prove-the-test-discriminates
Test regresji, którego nigdy nie widziałeś zawodzącego, to domysł. Zepsuj kod ponownie i patrz, jak robi się czerwony, zanim go zacommitujesz.
Nadane przez osobę, która przeczytała kartę, a nie deklarowane przez sam plik. Karta, którą agent destyluje podczas przebiegu z niezaufaną treścią, rodzi się skażona i czeka na recenzję, zanim kiedykolwiek zostanie pobrana.
Kiedy przychodzi na myśl
- napisany test regresji
- błąd poprawiony, test dopisany
- test przechodzi, można wypuszczać
- dopisywanie testu po poprawce
Wartość zwykle kryje się w Unikaj i Sprawdź. Rób to sekcja, którą pisze każdy.
Treść karty powyżej to tłumaczenie. Angielski oryginał jest tym, co importuje CLI, co agent czyta w czasie działania i czego dotyczy hasz poniżej.
Wyzwalacz
Naprawiłeś błąd i napisałeś test, żeby nie mógł wrócić. Test przechodzi. To cały dowód, jaki masz, i jest to ten sam dowód, jaki miałbyś, gdyby test nie sprawdzał o tym błędzie zupełnie nic.
Dotyczy najostrzej sytuacji, gdy test został napisany po poprawce, bo wtedy jedynym kodem, na którym test kiedykolwiek działał, jest kod, w którym błędu już nie ma. Dotyczy mniej testu napisanego najpierw, na czerwono, w pętli TDD — tamten już widziałeś zawodzącego, i o to w tej pętli chodzi.
Nie dotyczy testu dla naprawdę nowego zachowania, gdzie nie ma "przedtem", do którego można wrócić. Tam sprawdzenie różnicujące wygląda inaczej: usuń nową implementację i potwierdź, że test zawodzi na jej braku, a nie na błędzie.
Rób
- Zidentyfikuj dokładną edycję stanowiącą poprawkę — kawałek (hunk), nie commit. Jeśli poprawką jest jedno zmienione porównanie, to właśnie to porównanie cofniesz.
- Cofnij ją.
git stashna poprawkę albo ręcznie odwróć tę jedną linię do zepsutej postaci. - Uruchom tylko nowy test:
pytest tests/test_thing.py::test_the_regression -x. - Przeczytaj porażkę. Musi to być twoja asercja, która zawodzi, z komunikatem o zachowaniu —
nie
SyntaxError, nie błąd zbierania testów, nieImportErrorz połowicznie cofniętego pliku. Te są czerwone z niewłaściwego powodu i nie dowodzą niczego o teście. - Przywróć poprawkę (
git stash pop) i potwierdź, że ten sam test teraz przechodzi. - Zapisz ten fakt w docstringu testu: co zostało cofnięte i jak wyglądała porażka. Następna osoba dotykająca tego testu musi wiedzieć, że kiedykolwiek został on sprawdzony wobec błędu.
Unikaj
Sprawdzanie czegoś prawdziwego w obu światach. Klasyczny kształt:
result = parse_config(raw)
assert result is not None
assert "timeout" in result
Błąd polegał na tym, że timeout wracał jako string "30" zamiast int 30. Obie asercje zachodzą
w jednym i drugim przypadku. Różnicuje to, co się zmieniło:
# RIGHT — fails against the buggy code
assert parse_config(raw)["timeout"] == 30
assert isinstance(parse_config(raw)["timeout"], int)
Unikaj też cofania przez zakomentowanie całej funkcji albo usunięcie importu, żeby "szybko zrobiło się czerwone". To produkuje czerwone uruchomienie, które zdarzyłoby się dla dowolnego testu w tym pliku, więc nie mówi nic o tym jednym. Cofnięcie musi być poprawką i tylko poprawką.
I unikaj bliskiego chybienia, w którym test dociera do naprawionego kodu ścieżką, której produkcja
nigdy nie używa — to inna porażka, a kartą o niej jest chimera-test-the-wiring-not-the-class.
Sprawdź
Jedno pytanie zero-jedynkowe: czy osobiście widziałeś, jak ten test wypisuje porażkę spowodowaną własną asercją, wobec nienaprawionego kodu?
Jeśli tak, jesteś gotowy. Jeśli odpowiedzią jest "zawiódłby", nie sprawdziłeś niczego — to zdanie jest przewidywaniem wyprodukowanym przez to samo rozumowanie, które napisało test.
Mechanicznie:
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
Czerwony-potem-zielony, oba zaobserwowane, albo test jest nieudowodniony.
Ryzyko
Niektórych poprawek nie da się tanio cofnąć: aktualizacji zależności, migracji schematu, usuniętego pliku, zmiany w zwendorowanej bibliotece. Wymuszanie cofnięcia może tam kosztować więcej, niż wart jest test. Uczciwym rozwiązaniem zastępczym jest odtworzenie wejścia, które kiedyś to psuło, i sprawdzenie konkretnej wartości, a potem napisanie wprost w docstringu, że czerwone uruchomienie nie zostało zaobserwowane — nieudowodniony test, który przyznaje, że jest nieudowodniony, jest znacznie lepszy niż taki, który sugeruje, że został sprawdzony.
Prawdziwym zagrożeniem tej karty jest cofnięcie, którego zapomnisz odwrócić. Robienie tego tańca w
brudnym drzewie roboczym to sposób, w jaki ponownie zepsuta linia trafia do commita razem z własnym
testem regresji, przy zielonym zestawie, bo poprawkę przywróciłeś w złym pliku. Uruchamiaj git diff przed commitem, za każdym razem.
A test różnicujący jest tylko tak dobry, jak dobrze zrozumiałeś błąd. Dowodzi, że test wyłapuje to cofnięcie. Nie dowodzi, że naprawiłeś przyczynę źródłową, a nie objaw, a traktowanie przebiegu czerwony-potem-zielony jako dowodu na to jest twierdzeniem większym, niż dowód pozwala.
Jak użyć
Karta to dane. Sklonuj repozytorium i zaimportuj ją ścieżką — to, co przychodzi przez sieć, jest traktowane jako skażone i wstrzymywane do zatwierdzenia. Taki jest pożądany sposób działania i dlatego nie ma tu instalatora w jednej linijce.
git clone https://github.com/brcampidelli/chimera-agent.gitchimera skills-import chimera-agent/skills/chimera-prove-the-test-discriminates/SKILL.mdIntegralność
SHA-256 pliku w postaci opublikowanej. Importujący może sprawdzić, że otrzymał dokładnie to, co pokazała ta strona.
90d4bf00eb67055008527ee372153b2637fa2feea601ed6760997eda239f0b76