Przejdź do treści

Skills

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.

WzorzecPochodzenie: cleanStatus: activev0.1.0 · Apache-2.0

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

  1. 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.
  2. Cofnij ją. git stash na poprawkę albo ręcznie odwróć tę jedną linię do zepsutej postaci.
  3. Uruchom tylko nowy test: pytest tests/test_thing.py::test_the_regression -x.
  4. Przeczytaj porażkę. Musi to być twoja asercja, która zawodzi, z komunikatem o zachowaniu — nie SyntaxError, nie błąd zbierania testów, nie ImportError z połowicznie cofniętego pliku. Te są czerwone z niewłaściwego powodu i nie dowodzą niczego o teście.
  5. Przywróć poprawkę (git stash pop) i potwierdź, że ten sam test teraz przechodzi.
  6. 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.git
chimera skills-import chimera-agent/skills/chimera-prove-the-test-discriminates/SKILL.md

Integralność

SHA-256 pliku w postaci opublikowanej. Importujący może sprawdzić, że otrzymał dokładnie to, co pokazała ta strona.

90d4bf00eb67055008527ee372153b2637fa2feea601ed6760997eda239f0b76

Przeczytaj kartę w repozytorium