Zeszły tydzień zakończyliśmy eleganckim fakapem ekipy mBanku, która to ekipa „testowała na produkcji” powiadomienia push aplikacji mobilnej. W dużym skrócie, dla tych, co czytają ten tekst jakiś czas później, o poranku klienci mBanku otrzymali trzy powiadomienia push, w tym takie o treści „ęśąćż”. Ogólnie mało ciekawe zdarzenie i ktoś zapewne oberwał po uszach. O możliwych przyczynach na koniec. Teraz o testowaniu na produkcji.

Zanim zaczniemy

Załóżmy na chwilę, że jesteś architektem. Jednak nie takim od stawiania kloców w UML-u, ale takim prawdziwym, który projektuje budynki. Nie jesteś jednak zwykłym architektem, od projektowania kostki mazowieckiej. Jesteś architektem-urbanistą, czyli poza budynkami projektujesz też ich grupy ( systemy). Dostajesz zadanie zaprojektowania budynków, które będą spełniać pewne określone warunki. Ich dokładna treść nie jest istotna. Istotne jest jednak, że już na samym początku masz kilka różnych pomysłów. Każdy z nich będzie spełniał część warunków. W dodatku zbiór warunków, które spełniają wymyślone przez ciebie projekty, jest, mniej więcej, wspólny dla wszystkich pomysłów. Istnieje też pewna grupa warunków, których nie możesz przetestować na etapie projektowania. Co robisz?

Sytuacja wydaje się beznadziejna. Co prawda możesz odwołać się do swojego doświadczenia i spróbować intuicyjnie wybrać najlepsze rozwiązania. W przypadku małych elementów w projekcie, takich jak elementy mieszkania, możesz spróbować użyć wzorców projektowych Alexandra W. Czy jednak samo mieszkanie będzie dobrze zaprojektowane?

Na to pytanie próbowali odpowiedzieć Szwedzi z Instytut Badań Domowych W. Przeprowadzili oni badania nad zachowaniem gospodyń domowych w obrębie kuchni. Celem było zaprojektowanie kuchni funkcjonalnej. Do dziś wyniki tych badań są widoczne w projektach kuchni IKEA. Swoją drogą, badania te stały się też przedmiotem żartu w postaci filmu Historie kuchenne W, który to film gorąco polecam.

Można jednak podejść do problemu trochę inaczej. Pamiętaj, że mamy do opracowania NOWY projekt, a nie bazujemy na starych. Zrealizujmy więc większość naszych pomysłów na niewielką skalę. Zbadajmy, który spełnia wszystkie założenia, a następnie zrealizujmy go na większą skalę. Taki sposób myślenia przyświecał twórcom Osiedla Prototypów, na warszawskim Mokotowie. Więcej na temat samego osiedla tutaj. W dużym skrócie. W latach 60-tych wybudowano osiedle składające się kilkunastu budynków, które były budowane zgodnie z różnymi projektami. Były to zarówno pojedyncze budynki, jak i niewielkie zespoły urbanistyczne. Niektóre projekty różniły się szczegółami w rodzaju lustrzanego odbicia mieszkań albo innego ustawienia budynku w stosunku do stron świata.

Dzisiaj osiedle ma się chyba nieźle. Co prawda w latach 90-tych bardzo mocno dotknął je kryzys związany z transformacją, ale obecnie następuje już zmiana pokoleniowa i idzie ku lepszemu.

Testy na produkcji – oczywistości

Po przydługim wstępnie czas na mięsko. Po pierwsze testy na produkcji nie są czymś niezwykłym. Najpopularniejszym przykładem tego rodzaju działań są test A/B. Pozwalają one na porównanie różnych wersji elementów UI. Są stosunkowo tanie w porównaniu z testami laboratoryjnymi. Można też prowadzić je we w miarę bezpieczny sposób z punktu widzenia produktu. Nic więc dziwnego, że tego typu testy są często stosowane przy ocenie np. reklam. Przygotowujemy kilka wersji reklamy i patrzymy, która jest efektywna. Ba! Testy te, dla reklam, prowadzą nie tylko reklamodawcy, ale też (tak naprawdę, przede wszystkim) autorzy stron, gdzie reklamy są umieszczane. W końcu celem jest maksymalizacja kliknięć w reklamę. Jednak testy te nie są do końca tym, czym chcemy się tutaj zająć.

Drugim obszarem „na produkcji” są testy bliskie krzemu. Jak przetestować bootloader? Na emulatorze. Jednak koniec końców i tak trzeba przeprowadzić testy na fizycznym sprzęcie. Tak też dzieje się w przypadku ww. bootloadera. Ktoś odpala go na konkretnym sprzęcie i patrzy czy działa. Jest to czasochłonne i drogie, ale innej drogi nie ma. Zresztą dlatego tak ważna jest współpraca pomiędzy programistami kernela, a producentami sprzętu. Niektóre rzeczy można testować wcześniej. Oczywiście te testy są ograniczone. Tak naprawdę nie odbywają się „na produkcji”, a jedynie na środowisku takim jak produkcyjne. Czym to się różni? Fajny przykład podała Alicja Kubera na SegFaulcie:

Jak widzicie testy na kopii produkcji to jedno, a produkcja to drugie.

Część wspólna

Co łączy powyższe przykłady i przykład ze wstępu?

Łączy je trudność w wyborze rozwiązania, przy uwzględnieniu pewnych wymagań, których spełnienie nie może zostać zweryfikowane za pomocą testów w warunkach laboratoryjnych.

Czym są warunki laboratoryjne?

W przypadku testów jednostkowych mówimy, o ich powtarzalności, wzajemnej niezależności, niezależności wobec otoczenia, szybkości i możliwości automatyzacji. Dobre testy powinny ponadto być łatwe w implementacji, możliwe do uruchomienia przez każdego i niezmienne w stosunku do API (tylko zmiana API zmienia test). W przypadku testów wyższego poziomu, integracyjnych, e2e, rozluźniamy niektóre z powyższych warunków, ponieważ charakter testów tego rodzaju tego wymaga. Przykładowo trudno mówić o szybkich (trwających milisekundy) testach integracyjnych dla dużej liczby modułów.
Jednak wspomniane warunki laboratoryjne oznaczają, że testy można prowadzić w kontrolowanym i (w miarę) stabilnym środowisku. Pozwalają one na uzyskanie powtarzalnych wyników.

Mocki i inne zaślepki

Przy okazji warto wspomnieć o mockach i różnego rodzaju zaślepkach. Nie służą one do testowania naszego kodu. Ich zadaniem jest zapewnienie właśnie takiego stabilnego i w pewnym sensie sterylnego środowiska. Co prawda istnieje pewna niewielka nisza, gdzie weryfikacja stanu naszej zaślepki jest clou testu. Jednak w 99% przypadków „z życia” tak naprawdę testujemy bibliotekę, a nie nasz kod. Bardzo fajnie mówił kiedyś o tym Jose Valim, że funkcja powinna dostać wszystko, czego potrzebuje. Dzięki temu nie ma potrzeby korzystania z mocków.

Testy na produkcji – kiedy

Testy na produkcji prędzej czy później okazują się koniecznością. Co ciekawe mam pewną hipotezę na temat tego, kto wykonuje tego typu testy. Otóż są dwie grupy organizacji, które robią tego typu testy. Pierwsza grupa, to bardzo małe organizacje, które dostarczają produkty o niewielkim znaczeniu dla użytkownika końcowego. W takim przypadku taniej jest dostarczyć coś, co zostało przetestowane jednostkowo, a użytkownik końcowy przeklika sobie produkt i w razie czego zgłosi błąd. Szczególnie że błędy w takich produktach wynikają w dużej mierze z niedostatków w procesie projektowania. Dotyczą też rzeczy bliskich zagadnieniom, które obejmują testy A/B. Klasyką gatunku jest tu hasło „większe logo”. Czasami chodzi o inne umieszczenie przycisków, albo lekkie zmiany w procesie. Proces projektowania w takich produktach jest potraktowany po macoszemu nie ze względu na lenistwo czy niechęć do robienia porządnie, ale ze względu na oszczędność. Szkoda czasu na projektowanie hello worlda, choć i są fani tego typu zadań
Druga grupa to organizacje, które są po prostu gigantyczne. W ich przypadku nie opłaca się testować niektórych rzeczy, ponieważ ze względu na specyfikę klientów i tak nie pokryjemy wszystkich przypadków. W dodatku taniej wychodzi zrobienie dobrze niezadowolonemu klientowi na poziomie supportu niż przepalanie czasu testerów. Co ciekawe wielu błędów i tak nikt nigdy nie wykryje. Przy czym organizacje te mają dobrze zorganizowany proces wdrożenia i łatwo mogą wycofać wadliwy kod oraz mają sprawnie działający dział wsparcia, który potrafi (i może) identyfikować problemy z funkcjonalnościami.
Średniej wielkości organizacje zazwyczaj nie testują na produkcji. Z jednej strony mają już wystarczająco dużo środków, by testować laboratoryjnie. Z drugiej strony ich produkty nie są na tyle duże, by testerzy nie byli w stanie ogarnąć wszystkich zagadnień.

Osobną grupę stanowią dostawcy różnych krytycznych rozwiązań, którzy mają zupełnie inne podejście do problemu testowania, ale to temat na osobny wpis.

Podsumowanie

Trochę się rozwlekłem, więc szybkie podsumowanie. Testy na produkcji nie są czymś złym. Jeżeli potrafimy je wykonać, czyli mówiąc prościej, umiemy odkręcić ich rezultaty, to mogą okazać się niezłym narzędziem. Ważne jest też wypracowanie i przestrzeganie zasad tego typu testów. Inaczej może okazać się, że mamy problem jak mBank. A co tam padło? Najprawdopodobniej w narzędziu do wysyłania powiadomień tester nie zaznaczył grupy docelowej i poszło do wszystkich. Zapewne narzędzie było niedostatecznie przetestowane.