Oczekiwany wynik testu musi być niezależny od kodu agenta
Gdy agent generuje implementację oraz testy, może przenieść tę samą błędną interpretację wymagania do kodu i asercji. Wysokie pokrycie potwierdza wtedy, że test wykonał wadliwą ścieżkę, ale nie że rozpoznał niewłaściwy wynik.
Platforma developerska powinna zatem rozdzielać generowanie danych testowych od ustalania oczekiwanego wyniku. Generator może korzystać z kodu, pokrycia i analizy mutacyjnej, aby znaleźć interesujące wejścia. Wyrocznia testowa musi opierać się na niezależnym kontrakcie, wersji referencyjnej albo zatwierdzonym przykładzie zachowania.
Pokrycie wykonuje wadliwą ścieżkę częściej, niż wykrywa błąd
W badaniu skuteczności kryteriów testowych dla kodu generowanego przez LLM zebrano 6066 nietrywialnych błędnych implementacji. Powstały one z pięciu modeli i czterech zestawów zadań. Dla każdego kryterium autorzy sto razy losowali minimalny zestaw testów osiągający pokrycie całej dostępnej puli, a różnice sprawdzali testem Wilcoxona i miarą efektu Vargha–Delaneya.
Pokrycie instrukcji, pokrycie gałęzi i analiza mutacyjna doprowadzały test do odmiennego zachowania odpowiednio dla 32,9%, 38,9% i 32,2% badanych błędów. Asercje wykrywały jednak tylko około 1–2%. Różnice między trzema kryteriami były niewielkie, mimo znacznie wyższego kosztu analizy mutacyjnej. W tym eksperymencie problemem częściej okazywał się oczekiwany wynik niż brak wykonania odpowiedniej ścieżki.
Autorzy wykonali też osobny eksperyment: ukryli wadliwą implementację i przekazali modelowi wejście testowe wraz z opisem zadania. Dla zestawów dobieranych przez analizę mutacyjną asercje utworzone na tej podstawie podniosły wykrywalność średnio o około 6,6 punktu procentowego, lecz w najlepszych konfiguracjach nadal wykrywały najwyżej około 30% błędów. Odcięcie wyroczni od bieżącego kodu ograniczyło kopiowanie jego zachowania, ale opis w języku naturalnym nadal nie był wystarczająco precyzyjną specyfikacją.
Wynik dotyczy krótkich funkcji w Pythonie z benchmarków programistycznych, a nie usług Java ani wielomodułowych repozytoriów. Nie uzasadnia porzucenia pokrycia czy analizy mutacyjnej. Pokazuje natomiast, że są to miary eksploracji kodu, których nie należy traktować jako dowodu poprawności asercji.
Analiza programu poprawia kod agenta, lecz nie uzupełnia zamiaru projektanta
ExCoder, opisany w pracy przyjętej na ISSRE 2026, dostarcza drugi wynik na kodzie Java. Autorzy usunęli obsługę wyjątków z 304 metod w 75 publicznych projektach, a następnie próbowali ją odtworzyć na podstawie istniejących testów zachowania wyjątkowego.
Model otrzymywał kontekst z analizy statycznej — dostępne symbole i konstruktory wyjątków — oraz z wykonania programu: rzucone wyjątki, pokryte linie i testy zwykłego przebiegu. Dla Qwen 2.5 Coder 32B odsetek pierwszych odpowiedzi przechodzących wszystkie testy autora wzrósł z 73,36% do 85,92%. Po dołączeniu testów wygenerowanych przez EvoSuite i Randoop wynik wzrósł z 63,55% do 75,72%.
Bogatszy kontekst zwiększył liczbę użytecznych kandydatów, ale prawie nie zmienił odsetka fałszywych sukcesów wśród rozwiązań przechodzących testy: spadł on z 25,56% do 24,71%. W ręcznej ocenie implementacja ExCodera była równoważna z kodem referencyjnym dla 198 z 304 metod, czyli 65,13%. Wśród fałszywych sukcesów 63,08% miało zbyt łagodny warunek rzucenia wyjątku. Test pokazywał jeden przypadek wymagający wyjątku, lecz nie wyznaczał całej granicy między dozwolonym i niedozwolonym stanem.
To badanie również ma ograniczenia: brakującą obsługę wyjątków uzyskano syntetycznie przez usunięcie istniejącego kodu, a wygenerowane testy nie stanowią pełnego zapisu zamiaru autora. Dane pokazują jednak dwie niezależne własności potoku. Analiza statyczna i dynamiczna pomaga agentowi napisać kod zgodny z repozytorium. Nie dostarcza automatycznie semantycznej granicy, według której ten kod należy zaakceptować.
Potok QA potrzebuje osobnego źródła oczekiwanych wyników
W notatce o niezależnych kryteriach akceptacji rozdzieliłem kompletność zmiany, zachowanie, własności niefunkcjonalne i telemetrię po wdrożeniu. Nowe wyniki wymagają dalszego podziału samej kontroli zachowania:
- Generator kandydatów tworzy implementację i może korzystać z kodu repozytorium, typów, grafu wywołań, komunikatów kompilatora oraz śladów wykonania.
- Eksplorator wejść szuka wartości i sekwencji, które wykonują nowe gałęzie, zabijają mutanty albo różnicują starą i nową wersję. Może analizować kod kandydata, ponieważ jego zadaniem jest znaleźć miejsce potencjalnego błędu.
- Źródło oczekiwanego wyniku ustala asercję bez odczytywania zachowania kandydata. Wynik może pochodzić z wersji referencyjnej, testu kontraktowego konsumenta, modelu stanów, zatwierdzonego przykładu albo jawnego niezmiennika domenowego.
- Wykonawca porównawczy uruchamia te same wejścia na kandydacie i źródle referencyjnym, zapisując osobno wykonanie wadliwej ścieżki oraz wykrycie różnicy przez asercję.
Rozdział musi być widoczny także w uprawnieniach. Agent zmieniający implementację nie powinien w tym samym zadaniu nadpisywać kontraktu ani zaakceptowanych danych referencyjnych. Każda wyrocznia powinna mieć wersję i pochodzenie, aby przegląd kodu pokazywał, czy zmieniła się funkcja, oczekiwane zachowanie, czy oba artefakty naraz.
Dla obsługi wyjątków w Javie kontrakt powinien opisywać co najmniej typ wyjątku, granicę warunku, moment rzucenia i skutki uboczne wykonane przed przerwaniem operacji. Pojedynczy przykład negatywny należy uzupełnić przypadkami po obu stronach granicy. W przeciwnym razie agent może napisać warunek zbyt łagodny albo zbyt restrykcyjny, a wszystkie dostarczone testy nadal przejdą.
Raport z testów powinien oddzielać wykonanie błędu od jego rozpoznania
Brama CI dla zmian agentowych nie powinna kończyć raportu na liczbie zaliczonych testów i procencie pokrycia. Powinna wskazać, które wejścia odróżniły kandydata od referencji, dla ilu z nich istniała niezależna asercja oraz które wymagania nie mają jeszcze wyroczni. Dzięki temu wzrost pokrycia nie ukrywa braku decyzji o poprawnym wyniku.
Agent może generować dodatkowe wejścia i proponować asercje, ale propozycja asercji pozostaje zmianą kontraktu wymagającą osobnej akceptacji. Dla Solution Architecta oznacza to konkretny element platformy: wersjonowane źródło oczekiwanego zachowania oraz interfejs, który udostępnia je wykonawcy testów bez wyprowadzania odpowiedzi z implementacji podlegającej ocenie.
Wykorzystuję treści generowane przez AI jako część mojego codziennego procesu nauki.