Filar

Testy i symulacje stojące za Craft11

Każda porażka migracji, jaką kiedykolwiek widzieliśmy w innym oprogramowaniu, bierze się z tego samego miejsca: traktowania “najpierw uporządkuj dane” jako problemu klienta zamiast problemu produktu. Nie chcieliśmy tego budować. Więc wcześnie trafiliśmy na prawdziwy przypadek i nauczył nas czegoś, czego się nie spodziewaliśmy: czasem właściwą odpowiedzią na “czy powinno się tym zająć AI” jest nie.

Migracja, która nauczyła nas różnicy

Mieliśmy do przeniesienia prawdziwy eksport ze starego CRM-a: 349 firm, 491 notatek, głównie historię rozmów spisaną po słoweńsku, 393 kontaktów. Oczywistym posunięciem byłoby przepuszczenie tego przez Neo, nasz import wspomagany AI, ten sam, który czyta bałaganiarski arkusz i proponuje z niego czyste rekordy.

Zdecydowaliśmy, że nie. Dane źródłowe były już ustrukturyzowane, już rozstrzygnięte, już poprawne. Przepuszczenie ich przez przebieg AI nie dodałoby niczego poza ryzykiem: model parafrazujący lub streszczający prawdziwe słoweńskie notatki z rozmów, po cichu tracący precyzję w tekście, który musiał pozostać dokładnie taki, jaki był zapisany. Zbudowaliśmy więc drugą, oddzielną, celowo wolną od AI ścieżkę: dokładne, deterministyczne kopiowanie, dopasowywane po ID rekordu z systemu legacy, z zachowaniem oryginalnych znaczników czasu, bez żadnego modelu językowego nigdzie w środku.

Budowa tej ścieżki wydobyła na jaw prawdziwe luki, których inaczej byśmy nie znaleźli: pole formularza po cichu porzucane przez backend nie wiadomo jak długo, bo kolumna w bazie danych za nim nigdy nie istniała, kontakty upychane w notatkach z wolnym tekstem z braku właściwego miejsca do życia. Naprawiliśmy oba na stałe, nie tylko na potrzeby tej jednej migracji.

Taki jest teraz rzeczywisty kształt Migration Engine: Neo dla uczciwego bałaganu, rzućcie nam swój najgorszy arkusz, a powiemy wam wprost, co udało nam się z niego zrozumieć, a czego nie, oraz cicha, dokładna ścieżka kopiowania dla danych, które już są wiarygodne i muszą po prostu dotrzeć nietknięte. Dwa różne problemy. Przestaliśmy udawać, że to jeden.

Dojście w ogóle do czegoś wartego testowania

Nic z testów poniżej nie ma znaczenia, jeśli pod spodem nie ma nic prawdziwego. Szczerze mówiąc, część tego, jak tu dotarliśmy, zaczęła się przypadkiem. Nagrania ekranu wciąż były odkładane, głównie ze zwykłej niechęci, by usiąść i porządnie coś nagrać, więc prawdziwym obejściem było po prostu patrzenie, jak AI na żywo klika po aplikacji, i notowanie, co się dzieje. Okazało się to jedną z najlepszych metod debugowania, na jakie natrafiliśmy w całym projekcie, nie sprytnym planem, tylko produktem ubocznym niechęci do robienia czegoś innego. Kilka prawdziwych funkcji istnieje dziś dlatego, że bug został złapany dokładnie w ten sposób.

Większa budowa poszła podobnym torem, mniej z wielkiego planu, bardziej z konieczności: jeden prawdziwy kawałek na raz, każdy przetestowany od początku do końca, zanim zaczynał się kolejny, bo projekt tej wielkości inaczej nie pozostaje spójny. Co nas naprawdę zaskoczyło, to że bazowy pakiet testów w końcu zaczął przewidywać rzeczy, o które nikt go nie prosił. Dodajesz nową funkcję miesiące później, a Velvet czasem łapał, że jakiś sąsiedni fragment cały ten czas cicho stał w połowie gotowy, czekając, aż ktoś to zauważy. Nie dlatego, że ktokolwiek zaangażowany jest wyjątkowo spostrzegawczy. Test, który naprawdę klika przycisk i sprawdza rzeczywisty wynik, po prostu ma sposób na znajdowanie rzeczy, których osoba przeglądająca kod pobieżnie by nie znalazła.

Velvet

Gdzieś po drodze nasz własny pakiet testów end-to-end dostał imię zamiast pozostać po prostu “testami”. Nazywamy go Velvet. Około pięciu tysięcy linii Playwrighta, w dwunastu nazwanych zestawach, smoke, regresja, Vault, AI Village, przepływy action-bus, twarde przypadki brzegowe, stres, między innymi, uruchamiane na pięciu oddzielnych syntetycznych, obsadzonych danymi firmach testowych. Steruje rzeczywistą, działającą aplikacją, backend i frontend oba na żywo, bez zamockowanego zastępstwa dla żadnego z nich.

W nazwanych zestawach regresyjnych wywołania AI są zamockowane do deterministycznych odpowiedzi, celowo, nie jako skrót. Przy prawdziwej skali prawdziwe wywołania AI uderzają w limity połączeń przeglądarki i generują awarie, które nie mają nic wspólnego z tym, czy produkt faktycznie działa. Mockowanie izoluje tam jedno uczciwe pytanie, czy hydraulika działa, od innego, czy rzeczywista odpowiedź AI jest dobra, które testowane jest osobno, naprawdę.

Dyscyplina pod każdą warstwą

Pięć zasad obowiązuje wszędzie tam, gdzie w tym projekcie testuje się coś, nie tylko w Velvet:

Zapisać przewidywanie przed uruchomieniem testu, żeby zaliczenie nie mogło zostać potem po cichu przedefiniowane na to, co akurat się zdarzyło. Test, który tylko potwierdza istnienie przycisku, nie jest testem; musi kliknąć przycisk, poczekać na prawdziwą odpowiedź, łącznie z prawdziwym opóźnieniem AI, i sprawdzić rzeczywisty wynikowy stan. Każda funkcja jest wypróbowywana tak, jak powinna działać, i tak, jak faktycznie źle użyłaby jej prawdziwa, czasem nieuważna, czasem wroga osoba. Kiedy “awaria” okazuje się bugiem w skrypcie testowym, a nie w produkcie, to też jest zgłaszane, a nie po cichu łatane i zapominane. A poprawka nie jest gotowa, gdy kod się kompiluje; jest gotowa, gdy dokładnie ten scenariusz, który się zepsuł, został naprawdę uruchomiony ponownie i przeszedł.

Poza Velvet: siedem warstw, nie jedna

Velvet to jedna warstwa z siedmiu. Prawdziwa, niezamockowana weryfikacja AI działa osobno, jednorazowy skrypt uruchamiany na żywej aplikacji z prawdziwymi wywołaniami modelu, potem posprzątany, specjalnie po to, by złapać rodzaj buga, który pojawia się tylko dlatego, że odpowiedź prawdziwego modelu różni się między uruchomieniami. Symulacja długiego horyzontu odtwarza symulowane historie firm, miesiąc, rok, pięć lat, na prawdziwych najemcach z żywymi wywołaniami AI przez cały czas, zadając te same kanoniczne pytania w wielu punktach, by sprawdzić, czy odpowiedzi faktycznie stawały się trafniejsze w miarę narastania historii, nie tylko czy w ogóle wracały. Celowa warstwa adwersarialna, osiem wrogich testów, które nazywamy Torem Przeszkód, próbuje bezpośrednio złamać deklaracje produktu dotyczące uczciwości i bezpieczeństwa: prompt injection, wyciek danych między najemcami, sprzeczne instrukcje, odporność na usuwanie, prawdziwe uzgadnianie finansowe, obsługę zduplikowanych kont. Testy jednostkowe i integracyjne backendu obejmują Sacred Spine i wprowadzanie dokumentów od początku do końca. Prowadzone przejścia testują rzeczywisty interfejs przy prawdziwych rozmiarach ekranu, desktop i prawdziwy widok mobilny, ze zrzutami ekranu jako dowodem, nie zwykłym ptaszkiem na liście. Nawet prezentacyjne filmy zapowiedzi posłużyły jako warstwa testowa: każdy z nich to prawdziwy scenariusz uderzający w prawdziwą, żywą aplikację, a każdy moment, który przy przeglądzie wyglądał lekko nie tak, był indywidualnie prześledzony aż do prawdziwego buga albo problemu z synchronizacją skryptu, nigdy nie zakładano bez sprawdzenia, który to przypadek.

Łącznie, około dwudziestu pięciu symulowanych lat działalności biznesowej, kilka branż, ponad dziewięć tysięcy prawdziwych wpisów w Vault wygenerowanych po drodze, jedenaście prawdziwych bugów znalezionych i naprawionych. Całkowity rzeczywisty wydatek na API dla całego programu: 9,57 dolara.

Czego nie będziemy twierdzić

Nie przetestowaliśmy skali korporacyjnej, tysięcy jednoczesnych najemców naraz. Nie przetestowaliśmy obciążeniowo, co dzieje się z kosztem AI przy naprawdę intensywnym, otwartym codziennym czacie, w przeciwieństwie do zaskryptowanej aktywności biznesowej, wokół której zbudowano większość tych testów. Podczas powyższej pracy znaleźliśmy realne ryzyko skalowania we własnym uzupełnianiu embeddingów wstecz, jednorazowe nadganianie dużego Vault niebezpiecznie zbliżające się do limitu czasu żądania, i mówimy wam o tym zamiast po cichu to załatać i nic nie powiedzieć.

Nic tu nie jest idealne, bo nic nie jest. Za czym naprawdę możemy się opowiedzieć, to za tym, że dokładnie przyjrzeliśmy się własnym twierdzeniom, zanim wam je przedstawiliśmy, i że mówimy wam, co znaleźliśmy, tak czy inaczej. To cała dyscyplina. Będziemy to robić dalej.

Pytania, które ludzie naprawdę zadają

Czy Craft11 używa AI do migracji starych danych, czy to ryzykowne?

Jedno i drugie, zależnie od źródła. Bałagan, dane niestrukturyzowane, arkusz bez nagłówków, zeskanowany cennik, przechodzą przez Neo, wspomagany przez AI Migration Engine, który proponuje czyste rekordy i szczerze mówi, czego nie potrafił uzupełnić. Już ustrukturyzowane eksporty ze starych systemów idą osobną, celowo wolną od AI ścieżką: dokładne, deterministyczne kopiowanie. Zbudowaliśmy oba warianty, bo jedna prawdziwa migracja nauczyła nas, że to nie ten sam problem.

Czym jest Velvet?

Nazwą naszego własnego pakietu testów end-to-end w Playwright, około pięciu tysięcy linii w dwunastu nazwanych zestawach testów, uruchamianego na prawdziwych, obsadzonych danymi testowych firmach, sterującego rzeczywistą, działającą aplikacją, a nie jej zamockowaną wersją.

Czy coś w tym wszystkim jest idealne albo w pełni skończone?

Nie, i wolimy powiedzieć to wprost, zamiast pozwolić dużej liczbie sugerować co innego. Skala korporacyjna, tysiące jednoczesnych najemców, nie została przetestowana. Rzeczywisty koszt intensywnego, otwartego codziennego użycia AI nie był testowany obciążeniowo przy dużej skali. Podczas testów znaleźliśmy realne ryzyko skalowania we własnym procesie uzupełniania embeddingów wstecz i zgłosiliśmy je, zamiast po cichu naprawić i iść dalej. Testowanie oznacza tu, że sprawdziliśmy dokładnie i powiedzieliśmy prawdę o wyniku, a nie że nie zostało już nic do znalezienia.

Dołącz do Early Crew →← Powrót do wszystkich tekstów

Recorded on a live database and a live screen, but run by automated scripts standing in for a human's clicks and typing, not performed live. When Stark answers faster than the script expects, the screen can hold still for a beat before the next step starts. That's left in on purpose. The goal was never a polished demo reel, it was proof the feature actually works. Dejan's own verdict, after watching the raw footage: rough, but the best demo video we've made.