Po co recap
Jest 15 grudnia i kończę rok, w którym sztuczna inteligencja przestała być u mnie tematem na konferencję i zrobiła się tematem na code review. Rok temu zamykałem grudzień zdaniem, że ChatGPT jest piętnaście dni stary, że żaden mój test z 2022 nie powstał w rozmowie z modelem i że jeżeli będę miał o tym coś do powiedzenia poza pierwszym wrażeniem, to napiszę osobny wpis w przyszłym roku. Napisałem jedenaście. Ten tekst jest rozliczeniem tamtej obietnicy, a nie dwunastym tutorialem, więc nie znajdziecie tu ani jednego nowego pliku konfiguracyjnego.
Pytanie roku formułuję dokładnie tak: czy AI weszło do mojego zespołu QA, czy tylko do hype’u. To nie jest pytanie o nastrój, bo “w zespole” znaczy u mnie cztery bardzo konkretne rzeczy. Narzędzie ma nazwane zadanie. Ma miejsce w procesie, a nie w prywatnej zabawie po godzinach. Ma swój wiersz w pipeline albo świadomy powód, dla którego go nie ma. I ma człowieka, który odpowiada za jego wynik przed resztą zespołu.
Odpowiedź po dwunastu miesiącach jest węższa niż nagłówki i szersza niż zeszłoroczna. AI weszło do szkicu i do edytora. Nie weszło do ownershipu. Model pisze u mnie pierwszą wersję listy przypadków, pierwszą wersję pliku JSON pod fixture, pierwszą wersję planu testów i pierwszą hipotezę przy flake’u. Nie zatwierdza pull requesta, nie decyduje o zakresie regresji, nie jest właścicielem ani jednego ticketu i nie ma osobnego joba w moim CI. Zdanie, którym zamknę cały rok, jest kalką zdania z czerwca 2022 o ghost texcie: zmieniło się tempo szkicowania, nie zmieniła się granica odpowiedzialności.
Do tego dochodzi drobiazg, który w tekstach o 2023 ginie, a jest istotny akurat dziś. Najgłośniejsze narzędzie tego roku po stronie edytora, GitHub Copilot Chat, w dniu tego wpisu nadal nie jest ogólnie dostępne. O tym w sekcji o IDE.
Fundament dwóch lat
Zacznę od tego, czego rok modeli językowych nie skasował, bo to nadal większa część odpowiedzi niż wszystko, co dołożyłem.
Oś z 2021 stoi bez korekt. Podsumowanie 2021 było w całości o izolacji: kontener zamiast instalacji, stub zamiast cudzego środowiska, ziarno zamiast losowych danych, równoległość dopiero wtedy, kiedy stan nie wycieka. Przez dwanaście miesięcy z czatem pod ręką nie dostałem ani jednego powodu, żeby którekolwiek z tych zdań zmiękczyć. Wręcz odwrotnie: model, który produkuje dane testowe hurtowo, jest testem tego, czy mój zestaw naprawdę ma właściciela stanu, bo źle izolowany zestaw zasypany świeżym syntetykiem migocze szybciej, nie mniej.
Oś z 2022 też zostaje i to ona zdefiniowała, jak wyglądał ten rok. Copilot wyszedł z technical preview 21 czerwca 2022 z cennikiem 10 USD miesięcznie albo 100 USD rocznie i przez cały 2023 był u mnie tym samym narzędziem, czyli szarym tekstem przed kursorem. W kwietniu 2022 zdecydowałem o schodzeniu z Cypressa na Playwright i ta migracja w 2023 posunęła się dokładnie tak, jak posuwają się migracje: nowe testy przez przeglądarkę powstają w nowym runnerze, stary zestaw nadal jest zielony i nadal go nie kasuję. W lipcu 2022 doszły kontrakty consumer-driven, we wrześniu podział testów po triggerze, w listopadzie porównanie narzędzi do visual regression. Wszystkie te osie przetrwały rok bez jednej zmiany wymuszonej przez AI.
To jest kontekst, w którym trzeba czytać dwanaście miesięcy nowości. Nie startowałem z pustego repozytorium, tylko dokładałem szybkiego kolegę do zestawu, który już miał zasady.
Czat i modele
Rok po stronie modeli miał u mnie kształt schodów, a nie skoku.
W styczniu opisałem ChatGPT jako szkicownik przypadków testowych. Warto pamiętać, co to znaczyło w styczniu: sześciotygodniowy produkt web z 30 listopada 2022, bez planu płatnego, bez API i bez GPT-4. Wklejałem kryteria akceptacji, dostawałem listę, wykreślałem połowę i to, co zostało, szło do ticketu, nie do commita.
W lutym poszedł wpis o strukturze promptu do generowania test case’ów: rola, ograniczenia, format wyjścia, iteracja zamiast jednego strzału. To jest też miesiąc, w którym ta zabawa zaczęła mieć cenę, bo ChatGPT Plus wystartował 1 lutego w Stanach za 20 USD miesięcznie i od 10 lutego był dostępny poza nimi. Tego samego miesiąca, 7 lutego, Microsoft pokazał czat w Bingu, co odnotowałem jako drugi czat na rynku, a nie jako drugie narzędzie w warsztacie.
1 marca pojawiło się API gpt-3.5-turbo i to była pierwsza data w tym roku, która realnie zmieniła moją pracę, bo czat z przeglądarki przestał być jedyną drogą do modelu. Dwa tygodnie później, 14 marca, wyszedł GPT-4, więc wpis z 15 marca pisałem dzień po premierze i musiałem w nim postawić rozróżnienie, które przez cztery kolejne miesiące ludzie mylili najczęściej: model był w interfejsie ChatGPT Plus jako przełącznik, a API gpt-4 było na waitliście. Ogólna dostępność tego API dla płacących klientów przyszła dopiero 6 lipca.
W czerwcu domknąłem wątek danych: syntetyczne fixture z gpt-3.5-turbo, najpierw kontrakt danych, potem prompt, potem walidacja schematem i dopiero wtedy plik w repozytorium. Dwa dni przed tamtym wpisem, 13 czerwca, OpenAI dodało function calling, co odnotowałem jako świeżą nowość, a nie rdzeń procesu. Kontrast, który stawiam przy tym temacie od dwóch lat, zostaje bez zmian: eksperyment z Completions i modelem davinci z 2021 miał tę samą konkluzję co czerwiec 2023. Dwa wywołania z tym samym wejściem nie muszą dać tego samego wyniku, więc to jest narzędzie do wymyślania danych, a nie źródło prawdy w przebiegu CI. Zmienił się endpoint i cena, nie zmieniła się natura artefaktu.
Lipiec zszedł mi na triage’u. Wklejałem nazwę testu, fragment logu i informację, czy padło na pull requeście czy w nocy, a dostawałem trzy hipotezy do sprawdzenia: race na porcie, współdzielony fixture, retry maskujący problem danych. Każdą potwierdzałem odtworzeniem i nie każda się broniła. Model zwalał winę na “flaky Selenium” w projekcie, w którym Selenium nie ma, i proponował sleep jako rozwiązanie. To był mój najwyraźniejszy miesiąc roku pod jednym względem: AI generuje hipotezy szybciej niż ja, ale ownerem ticketu i tak zostaję ja, bo to ja umiem odtworzyć.
Konkurencja w tym roku istniała i wypisuję ją jako nagłówki, nie jako narzędzia, którymi pracowałem: Claude od Anthropica z 14 marca, Bard z 21 marca, Claude 2 z 11 lipca i Llama 2 z 18 lipca. Nie zbudowałem na żadnym z nich ani jednego kroku w pipeline.
Czat w IDE
Drugi wątek to edytor i on ma w tym roku najbardziej mylącą chronologię, więc rozpiszę ją datami.
W kwietniu napisałem o recenzowaniu sugestii Copilota w testach C# i to jest wpis o ghost texcie, nie o czacie, bo w kwietniu czatu w moim edytorze jeszcze nie było. Copilot X ogłoszono 22 marca, a Copilot Chat był w nim technical preview za waitlistą. Zapowiedziany Copilot for PRs opisałem tak, jak wtedy wyglądał, czyli jako listę oczekujących.
W maju wpuścili mnie do preview i wtedy padł setup, który trzeba zapamiętać, bo dobrze pokazuje, jaki to był etap produktu: VS Code Insiders plus rozszerzenie GitHub Copilot Nightly plus aktywna subskrypcja. Nie stabilny edytor, nie jedno kliknięcie w marketplace.
Dalej dostępność rosła etapami, na które nie miałem wpływu. 20 lipca czat wszedł w public beta dla organizacji z planem Copilot for Business. 20 września w public beta dla osób indywidualnych, czyli pięć dni po moim wrześniowym wpisie o piramidzie, w którym musiałem jeszcze napisać, że nie każdy subskrybent to ma. 8 listopada, na GitHub Universe, ogłoszono, że ogólna dostępność przyjdzie w grudniu. I tu jest puenta tej sekcji, którą stawiam wprost, bo za rok będzie brzmiała nieprawdopodobnie: piszę te słowa 15 grudnia i Copilot Chat nadal nie jest GA. Mam obietnicę z listopada i mam betę w edytorze. Nie mam produktu ogólnie dostępnego.
Dlatego rachunek za AI w moim warsztacie jest w tym roku krótki i mieści się w dwóch oficjalnych pozycjach cennika: 20 USD miesięcznie za ChatGPT Plus i 10 USD miesięcznie albo 100 USD rocznie za Copilota. Wszystko inne to preview, beta i waitlisty.
Jedno zdanie o rzeczy, o którą pytają mnie od wiosny: edytor Anysphere o nazwie Cursor istnieje, wypłynął na Hacker News w marcu i w październiku wziął rundę seed, ale nie był w 2023 moim codziennym narzędziem i nie ma w tym recapie nic więcej do powiedzenia na jego temat.
Playwright i piramida
Trzeci wątek jest cichszy i to on odpowiada na pytanie, czy AI zmieniło kształt mojego zestawu testów.
W sierpniu wziąłem się za component testing w Playwrighcie. Paczka nazywa się @playwright/experimental-ct-react, na sierpniowym pinie 1.37.0, i pierwsze słowo w tej nazwie jest ważniejsze niż cały wpis. Preview jest od 1.22.0 z maja 2022, więc to nie była nowość sierpnia, a mimo półtora roku nadal nie ma GA. Mount pojedynczego komponentu w prawdziwej przeglądarce jest szybszy od pełnego E2E i to działa, ale eksperymentu nie wpinam do pliku, od którego zależy merge do main, i nie buduję na nim konwencji projektu. To samo zdanie napisałem w grudniu 2022 i nie musiałem go w tym roku poprawiać.
We wrześniu zapytałem wprost, czy po pół roku czatu i preview czatu w IDE zmieniły mi się proporcje zestawu. Nie zmieniły. Piramida testów nie jest wynalazkiem 2023 roku, jest z książki Cohna i z tekstów Fowlera, i AI jej nie odkryło ani nie spłaszczyło. Dół piramidy przyspieszył, bo helper i kolejny [InlineData] powstają szybciej. Środek nie ma skrótu, bo model nie stoi za schematem kontraktu ani nie wie o mojej bazie tego, co wie SQL. Góra jest droga jak była, więc E2E nadal płacę wall-clockiem w nocy.
Konsekwencja praktyczna jest jedna i trzymam się jej cały rok: w moim CI nie ma joba “LLM”. Podział po triggerze z 2022 nie dostał piątego koszyka na modele. Pull request bierze to, co szybkie i deterministyczne, main bierze prawdziwe zależności, noc bierze pełne E2E i macierz silników. Jeżeli model pomógł napisać test, ten test wpada do jednego z tych trzech koszyków według tego, co sprawdza, a nie według tego, kto go szkicował. Listopadowa matryca visual regression zostaje bez zmian, ze screenshotami w koszyku nocnym, i nadal najtrudniejsze w niej jest to, kto zatwierdza nowy wzorzec, a nie która biblioteka porównuje piksele.
Pin Playwrighta, na którym zamykam rok, to 1.40.1 z 28 listopada.
Dokumentacja i security
Dwa ostatnie miesiące poszły na tematy, które z AI mają mniej wspólnego, niż wygląda z tytułów.
Październik zszedł na dokumentacji testowej pisanej przez model. Wnioski są dokładnie takie, jak w styczniu, tylko o innym artefakcie: LLM jest dobry jako pierwszy draft planu testów, checklisty kryteriów akceptacji i pliku README z instrukcją odpalenia zestawu, pod warunkiem że wejściem jest ticket albo kod, a nie pamięć modelu o typowej aplikacji. Custom instructions, dostępne od 20 lipca, przydały się tu bardziej niż nowy model, bo wymuszają język, format i zakaz wymyślania nieistniejących jobów. Recenzja skreśla za każdym razem to samo: środowiska, których nie mamy, docker compose pomylony z wersją pierwszą i wymyślony target w Azure. Merge dokumentacji traktuję jak merge kodu.
Listopad to były podstawy testów bezpieczeństwa dla QA i to jest dziura, której model nie zamyka. OWASP Top 10 w edycji 2021 jako mapa ryzyk zamiast checklisty czterystu narzędzi, ZAP baseline jako dym na środowisku testowym z progiem na wysokie znaleziska, Burp ręcznie przy uwierzytelnianiu i syntetycznym zasobie bez sprawdzenia właściciela. To nie jest pentest, nie jest to program bug bounty i nie jest to AI red-teaming. To minimum, przy którym zielone E2E przestaje być argumentem, że nie ma dziury w kontroli dostępu.
Nagłówek listopada, którego nie da się pominąć w recapie, jest z 6 listopada. Na OpenAI DevDay pokazano GPT-4 Turbo, GPTs i Assistants API. Odnotowuję to jako datę, nie jako proces, bo w moim listopadzie nie powstał ani jeden GPT i ani jedna linia wołająca Assistants. Drugi nagłówek jest z 14 listopada: wyszedł .NET 8. Mój tegoroczny stack jedzie na .NET 7 i tak zamykam grudzień, z tego samego powodu, z którego rok temu nie brałem siódemki w grudniu.
Co świadomie zostawiam na 2024
Wypisuję to, bo za rok nie będę pamiętał, że były to decyzje, a nie przeoczenia.
Autonomiczni agenci i samonaprawiające się testy. Projekty tego typu przewinęły się przez wiosnę i przez połowę rozmów, które w tym roku miałem o testach, a u mnie nie weszły do zestawu ani na minutę. Nie mam narzędzia, które samo poprawia lokator i samo wypycha commit, i nie chcę go mieć, dopóki nie umiem odpowiedzieć na pytanie, kto podpisuje ten diff. To jest temat na przyszły rok, z uczciwie zmierzonym wynikiem.
GPTs i Assistants API. Osiem dni różnicy między DevDay a moim listopadowym slotem to za mało, żeby napisać cokolwiek poza streszczeniem keynote’u.
Testcontainers Cloud. Public beta jest od 25 stycznia, czyli od początku tego roku, i przez dwanaście miesięcy nie znalazłem dnia, żeby to porządnie sprawdzić. Zapisuję jako temat, nie jako opinię.
NUnit 4.0.0 wyszedł 26 listopada. Trzy tygodnie przed końcem roku to najgorszy moment na przepisywanie zestawu i na tutorial roku, więc listy zmian mam przeczytane i odłożone na styczeń, dokładnie tak samo jak .NET 8.
Component testing zostaje eksperymentem, bo tak jest oznaczony przez producenta, a nie bo mi się nie chce.
Mierniki
Rok temu zapisałem sobie dwie liczby i tylko one interesują mnie w tym rozliczeniu.
Pierwsza to wall-clock samych wymaganych checków na pull requeście. Po wrześniowym podziale z 2022 bramka zeszła u mnie z trzydziestu czterech minut do siedmiu i w tym roku ta liczba się nie pogorszyła, mimo że przez zestaw przeszedł nowy runner, nowe dane i sporo kodu, którego pierwszą wersję szkicował model. Druga to odsetek nocnych przebiegów, w których coś padło bez zmiany w kodzie. Ta jest ważniejsza i trudniejsza, bo w roku, w którym łatwo wygenerować dwieście nowych przypadków w kwadrans, migotanie rośnie ciszej niż czas przebiegu.
Liczba, której nie mierzę, też ma nazwę i to jest pokusa dokładnie tego roku. Nie interesuje mnie, ile modeli, wtyczek i czatów mam włączonych. Nie interesuje mnie, ile przypadków testowych model napisał, bo koszt nie siedzi w pisaniu, tylko w utrzymaniu i w czytaniu wyniku. Tempo szkicowania urosło mi w 2023 realnie i to nie jest to samo co wzrost jakości.
Jedno zdanie na 2024: chcę, żeby moja odpowiedź na pytanie “gdzie w tym procesie jest AI” nadal dała się powiedzieć w jednym zdaniu, i żeby to zdanie nadal zawierało czasownik “recenzuję”.
Do zobaczenia w styczniu.

