Steven
Steven6 min czytania

Anatomia dowożenia oprogramowania do perfekcji: jak przegląd kodu wyłapał to, czego testy nie mogły

W całej serii GeekBye v2 powtarza się to samo: poprawka przechodzi każdy test na maszynie programisty, a potem przegląd kodu dowodzi, że zawiodłaby niemal u każdego. Oto workflow stojący za dziewięcioma wydaniami — bramka przeglądu, wychwyty na etapie poprawki i dyscyplina testowania-przed-wysyłką, która zamienia „u mnie działa" w „działa".

Inżynieria
Proces
Przegląd kodu
Wydania GeekBye
Anatomia dowożenia oprogramowania do perfekcji: jak przegląd kodu wyłapał to, czego testy nie mogły

W ciągu kilku tygodni GeekBye wypuściło dziewięć wydań — od v2.0.0 do v2.0.11 — a ta seria opowiedziała historię każdego z nich. Przeczytaj je razem, a wyłania się wzorzec ciekawszy niż jakikolwiek pojedynczy błąd: raz za razem poprawka przechodziła każdy test na maszynie programisty, a przegląd kodu dowodził, że zawiodłaby niemal u wszystkich pozostałych.

Ta luka — między „u mnie działa" a „działa" — to miejsce, w którym naprawdę mieszka niezawodność. Oto workflow, który ją zamyka, i indeks każdego wydania, które wyprodukował.

Wzorzec: zielone testy, zła odpowiedź

Oto trzy najbardziej wyraziste przypadki z serii, bo czynią abstrakcję konkretną.

  • W poprawce przechwytywania na wielu monitorach (v2.0.10) pierwsza implementacja zakotwiczała przechwytywanie ekranu na oknie nakładki aplikacji. Przeszła testy — na deweloperskiej maszynie z jednym monitorem. Przegląd zastanowił się, gdzie ta nakładka tak naprawdę żyje (na ekranie głównym, zawsze, chyba że fizycznie ją przeciągniesz) i dowiódł, że „poprawka" rozwiązałaby się z powrotem do złego monitora u niemal każdego prawdziwego użytkownika. Właściwa kotwica — kursor — wzięła się z tego rozumowania, a nie z przebiegu testu.
  • W wydaniu z awaryjnym trybem WebSocket (v2.0.8) przegląd wykrył, że dokładnie ten 403, który zwraca blokujące proxy, był klasyfikowany jako krytyczny błąd uwierzytelnienia — więc awaryjny tryb, dla którego uruchomienia funkcja w ogóle istniała, nigdy nie mógł się włączyć. Funkcja wyszłaby, przeszła testy szczęśliwej ścieżki i nie zrobiła nic dla swojej faktycznej publiczności.
  • W poprawce limitu bezczynności (v2.0.9) pierwsza wersja stemplowała zegar „wciąż żyję" wewnątrz ścieżki kodu, którą pewna część transkryptów zgodnie z prawem pomija — te od drugiego rozmówcy. Przegląd wychwycił, że przyszła zmiana mogłaby po cichu ponownie wprowadzić dokładnie ten naprawiany błąd, więc znacznik przeniesiono w miejsce bezwarunkowe, z testem, który go tam utrzyma.

Żaden z nich nie został wychwycony przez uruchomienie kodu. Wszystkie wychwycił recenzent rozumujący o tym, dlaczego kod działa — i znajdujący przypadek, w którym nie działa.

Trzy części bramki

Workflow stojący za serią nie jest wyszukany. To trzy nawyki stosowane bez wyjątku.

1. Przegląd rozumuje o poprawności, a nie tylko uruchamia kod. Przechodzący test dowodzi, że kod działa dla przypadku, o którym pomyślałeś. Przegląd to drugi, adwersaryjny model systemu pytający o jakim przypadku nie pomyślałeś? — drugi monitor, firmowe proxy, transkrypt pomijający gałąź, klient o jedną wersję w tyle. Krok przeglądu w tej serii często był niezależnym recenzentem-agentem poproszonym o obalenie poprawki, a nie jej pobłogosławienie. Cała rzecz tkwi w tym ujęciu: recenzent próbujący złamać twoje rozumowanie znajduje dziurę, którą recenzent próbujący ją zatwierdzić przemyka wzrokiem.

2. Każda poprawka zachowania wychodzi z testem przybijającym dokładną awarię. Nie testem, że funkcja działa — testem, że ten konkretny błąd jest martwy. 403 z zablokowanego proxy musi przejść do awaryjnego trybu; prawdziwy 403 uwierzytelnienia nie może. Zegar aktywności musi ostemplować transkrypt, który pomija atrybucję. Te testy istnieją, żeby błąd nie mógł po cichu wrócić za pół roku, gdy ktoś będzie refaktorował obok — awaria jest przybita do podłogi.

3. Build jest notaryzowany i zweryfikowany, zanim wyjdzie. Kilka z tych poprawek przeszło od diagnozy do podpisanego, notaryzowanego, samoaktualizującego się wydania w ciągu jednego dnia. Ta szybkość jest bezpieczna tylko dlatego, że bramka jest zdyscyplinowana: diagnostyka dowodzi przyczyny źródłowej (wydanie z uprawnieniem do mikrofonu wypuściło swoją diagnostykę najpierw), test przybija poprawkę, przegląd obala rozumowanie i dopiero wtedy wychodzi prawdziwy notaryzowany build. To rygor czyni szybkość bezpieczną, a nie coś, co się z nią wymienia.

Dlaczego ma to większe znaczenie dla aplikacji AI

Jest powód, dla którego ta dyscyplina jest nienegocjowalna akurat dla narzędzia takiego jak GeekBye. Kilka z najpaskudniejszych błędów w serii było cicho-błędnych, a nie głośnych awarią: zrzut ekranu, który podał AI zły monitor (v2.0.10), transkrypcja przechylona ku śmieciowym terminom, tak że „speak" wyszło jako imię (v2.0.11), asystent odpowiadający w złym trybie bez możliwości, by to zobaczyć (v2.0.3 + v2.0.5). Gdy twoja aplikacja podaje kontekst modelowi, złe wejście produkuje pewne siebie złe wyjście i nigdzie żadnego błędu. Nie da się wytestować wyjścia z awarii, które nie rzucają wyjątku. Trzeba się z nich wyrozumować — a od tego właśnie jest bramka przeglądu.

Seria, po kolei

Każdy z nich jest samodzielnym studium przypadku jednego wydania. Przeczytane od początku do końca, są anatomią prowadzenia produktu od „działa" do „godny zaufania".

  1. Ile naprawdę kosztuje wersja 2: 206 commitów uczciwych stanów — v2.0.0. Fundament: nigdy nie pokazuj stanu, który nie jest prawdziwy.
  2. Dzień, w którym nasza aplikacja zDDoSowała samą siebie — v2.0.1 + v2.0.4. Zaległości uploadu przy starcie tratujące nasz własny backend i drabina żywotności, którą wymusiły.
  3. Spokojne oprogramowanie: naprawa migotania i plakietka trybu odpowiedzi — v2.0.3 + v2.0.5. Wydania bez funkcji, które kupowały zaufanie po jednym szczególe naraz.
  4. Twoja aplikacja na Maca zapomina dostęp do mikrofonu przy każdym uruchomieniu — v2.0.6. macOS App Translocation i wypuszczenie diagnostyki przed poprawką.
  5. Jedna zmienna CSS, pięć rund przeglądu i toolchain Swift, który skłamał — v2.0.7. Jednolita półprzezroczystość i binarka, która zmieniła rozmiar, bo dokumentacja nie zgadzała się ze skryptem egzekwującym.
  6. Transkrypcja na żywo, gdy firewall blokuje WebSockety — v2.0.8. Awaryjny tryb czysto-HTTPS i 403, który ukryłby go przed nim samym.
  7. Dlaczego Twój notatnik AI przestaje nagrywać w środku spotkania — v2.0.9. Licznik bezczynności, który słyszał tylko ciebie, i awaria, która mogła zablokować twój pulpit.
  8. Dlaczego nagrywanie ekranu przechwytuje zły monitor — v2.0.10. Błąd złego ekranu i poprawka, która przeszła na jednym monitorze, a zawiodłaby na dwóch.
  9. Dlaczego transkrypcja AI przesłyszy techniczne terminy — v2.0.11. Przechylanie mowy ku twojemu słownictwu — i regresja, która pogorszyła sprawę, zanim ją poprawiła.

Wniosek

Perfekcja nie jest stanem, który się osiąga; to bramka, którą się utrzymuje. Dziewięć wydań i te same trzy pytania przy każdym: o jakim przypadku nie pomyślałeś, czy dokładna awaria jest przybita testem i czy prawdziwy podpisany build faktycznie wyszedł? Nic z tego nie jest efektowne. Wszystko z tego jest powodem, dla którego GeekBye v2 sprawia wrażenie spokojnego. Jeśli budujesz oprogramowanie — AI czy inne — przenośną częścią nie jest żadna pojedyncza poprawka. To nawyk traktowania zielonego zestawu testów jako początku argumentu, a nie jego końca.

Każde powyższe wydanie jest dostępne przez automatyczną aktualizację. O produkcie, w który te poprawki się składają, przeczytaj co nowego w GeekBye v2.

Powiązane artykuły

Twoja aplikacja na Maca dostaje dostęp do mikrofonu — i zapomina o nim przy każdym uruchomieniu
Steven
Steven5 min czytania

Twoja aplikacja na Maca dostaje dostęp do mikrofonu — i zapomina o nim przy każdym uruchomieniu

GeekBye poprosił o dostęp do mikrofonu, przyznałeś go, i zadziałało. Następne uruchomienie: zniknął. A aplikacja w ogóle nie pojawiła się w Ustawieniach systemowych → Mikrofon. Winowajcą była funkcja bezpieczeństwa macOS, po cichu uruchamiająca aplikację ze ścieżki, która znika — oto diagnoza i naprawa jednym kliknięciem.

macOS
Uprawnienia
Inżynieria
Jedna zmienna CSS, pięć rund review i toolchain Swift, który skłamał
Steven
Steven6 min czytania

Jedna zmienna CSS, pięć rund review i toolchain Swift, który skłamał

GeekBye v2.0.7 uczyniło całą nakładkę regulowanie przezroczystą — co brzmi jak jednolinijkowa zmiana w CSS i absolutnie nią nie było. Prawdziwa historia to to, co wychwyciło code review: dwie powierzchnie, które odmawiały gaśnięcia, pasek nagrywania, który wyglądał źle przy tej samej przezroczystości, oraz skompilowany plik binarny, który skakał o 672 bajty, bo nasza własna dokumentacja podała recenzentowi błędną wersję Swift.

Inżynieria
Projektowanie
Kompilacja
Zabezpieczenie, przez które nie dało się zamknąć naszej aplikacji
Steven
Steven5 min czytania

Zabezpieczenie, przez które nie dało się zamknąć naszej aplikacji

Automatyczna aktualizacja była najtrudniejszą funkcją, jaką kiedykolwiek wypuściliśmy — sześć wydań w cztery dni, żeby przestała psuć aplikację. Najgorszy błąd był tym, który wprowadziliśmy, próbując być ostrożni: 500-milisekundowe „zabezpieczenie", które zmieniało nieudaną aktualizację w proces, którego dosłownie nie dało się zamknąć.

Inżynieria
Electron
Niezawodność