Kilka refleksji o zawodzie testera. Weryfikacja, narzędzia i postawy

Słowo tester ma w języku polskim bardzo szerokie zastosowanie – od próbek perfum po urządzenia typu tester wody, tester prędkości. Stosuje się je także w stosunku do ludzi, zajmujących się weryfikowaniem działania różnych utensyliów, od prostych urządzeń i narzędzi po bardzo skomplikowane mechanizmy, na testerach oprogramowania kończąc.

Testowanie oprogramowania jest podporządkowane jednemu celowi: weryfikacji. Determinuje on kompetencje, które rozwija inżynier testów oprogramowania, narzędzia, z których korzysta, oraz procesy, które kształtuje. Jest to element, który w zasadniczy sposób odróżnia specjalistę testów od pozostałych pracowników branży IT. Czytając i przeglądając branżowe źródła, mam wrażenie, że ten fakt jest marginalizowany. Dyskusje toczą się wokół narzędzi (Selenium, ReadyAPI, Jira, Excel) lub procesów (święta wojna agile vs. waterfall). Niewiele jest namysłu nad procesem weryfikacji. 

Bogactwo narzędzi i metod odwraca uwagę testera od istoty zawodu. Wymagania i dokumentacja powinny być pierwszą rzeczą, na którą zwraca uwagę tester. Mam tu na myśli prozaiczną umiejętność czytania tekstu, analizowania, wybierania rzeczy które można „zważyć” i zmierzyć.

Weryfikacja jest zagadnieniem bardzo ciekawym i złożonym. Zależy od kontekstu, w którym inżynier testów funkcjonuje, również od kultury organizacyjnej. Inne problemy rozwiązuje inżynier testujący systemy ERP (Enterprise Resource Planning), inne inżynier testujący systemy przetwarzania big data, jeszcze inne testujący sztuczną inteligencję. Co więcej: poziom dokładność i formalizacji jest również zmienny. Nie ma sensu stosować metod kontroli rodem z elektrowni atomowych do rozwiązań dla mediów społecznościowych. Ale czy to samo byśmy powiedzieli o systemach medycznych, od których zależy podanie odpowiedniej dawki leku lub o systemach wsparcia kierowcy?

Sprawę dodatkowo komplikuje obszar, w którym się poruszamy. Tester, będący członkiem zespołu produkującego oprogramowanie (R&D), ma ułatwione zadanie w tak zwanym shift left – praktyce, mającej na celu znajdowanie i zapobieganie bugom na wczesnym etapie dostarczania oprogramowania. W tym przypadku zaangażowanie testera może funkcjonować bardzo efektywnie już na etapie analizy i przygotowania architektury.

Shift left, czyli przesunięcie testowania w lewo, jest trudniejsze dla testera zajmującego się testami integracyjnymi po stronie zewnętrznego odbiorcy. Tutaj nowe/zmieniane oprogramowanie jest tylko fragmentem większego horyzontu technologicznego. W takich wypadkach, często u odbiorcy, nie istnieje środowisko deweloperskie. Środowiska nieprodukcyjne wykorzystywane są do rozmaitych celów, czasami nawet sprzecznych. Skrajnym przypadkiem jest realizacja testów na środowisku produkcyjnym. Z perspektywy dostawcy oprogramowania scenariusz bardzo wygodny: nieograniczone źródło danych wszelakich i testerskiego szczęścia – stabilności systemów trzecich. Dla odbiorcy krok do katastrofy.

Jeszcze inaczej do weryfikacji będzie podchodziła osoba zajmująca się testami biznesowymi. W tym wypadku zagadnienia techniczne są właściwie drugorzędne. Tutaj znaczenie ma proces, weryfikacja tego, czy będzie on działał na modyfikowanym stosie technologicznym.

Konkretne pytania

Testowanie nie polega wyłącznie na poszukiwaniu odpowiedzi na pytanie o to, czy program robi to, co miał robić. Odpowiedź twierdząca (lub jakiś stopień przybliżenia) zadowoli, oczywiście, naszych przełożonych, ale stanie się to tylko wtedy, gdy zmieścimy się w czasie. A więc musimy weryfikować sprytnie i wydajnie! Musimy znać i rozwijać techniki upraszczania i klastrowania problemów.

Drugim równie ważnym pytaniem jest to, czy program robi coś, czego miał nie robić. Tutaj odpowiedź jest już trudniejsza – wymaga nie tylko wiedzy, ale także doświadczenia oraz intuicji. Są sytuacje oczywiste: oczekiwaliśmy na wynik przetwarzania faktury, a system wygenerował pustą kartkę. Wiadomo, że to błąd! Jeżeli system źle zaokrągla kwoty w obliczeniach pośrednich, gubi losowo dane, pozwala na nieautoryzowane przejęcie sesji użytkownika lub nie działa na zmigrowanych danych, to problem staje się bardziej złożony. Z tego powodu jakość jest odpowiedzialnością każdego uczestnika projektu: od pomysłu do przemysłu. Jest to bardzo ważny krok w procesach wytwarzania oprogramowania. Dzięki temu rola inżyniera testów może bardziej skupić się na weryfikacji.

Syndrom „operatora”

Każdy test jest eksperymentem, zderzeniem prognozy z diagnozą. Definiowanie prognozy jest sztuką samą w sobie. Wymaga skrajnej jednoznaczności i kwantyfikowalności połączonych z lapidarnością. Jest to sztuka odróżniania efektu od jego przyczyny. Napisano na ten temat już wiele książek, a mimo to jest on nadal przemilczany w dzisiejszych dyskusjach. 

Tester oprogramowania sprawdza, czy implementacja funkcjonalności odpowiada wymaganiom lub oczekiwaniom klienta, biznesu czy innych odbiorców/użytkowników. O wielości i złożoności tych czynników decyduje kontekst, w którym funkcjonuje tester. Innych środków wymagają testy integracyjne, innych testy bezpieczeństwa, a jeszcze innych testy wydajności lub migracji. Wszystkie one jednak skupiają się wokół weryfikacji założeń. Zderzeń rzeczywistości z oczekiwaniami.

Cel pracy testera jest inny od celu pracy programisty. Programiści są szkoleni w budowaniu oprogramowania przy optymalnym wykorzystaniu nakładów i środków. Testerzy ćwiczą się, aby przy tak samo optymalnym wykorzystaniu nakładów budować eksperymenty weryfikacyjne, korzystając przy okazji z produktów pracy programistów. Innym jest pytanie „jak napisać funkcję dodającą do siebie liczby”, a zupełnie czymś innych „jak przetestować, czy funkcja poprawnie dodaje liczby”. Odpowiedź na pierwsze pytanie to źródło dochodów programisty. Źródłem zasobów finansowych testera jest odpowiedź na drugie. „Zintegrowanie” tych dwóch podejść doprowadzić może do efektu „świnki morskiej”.

Efekt ten ujawnia się szczególnie w przypadku automatyzacji testów. Każde narzędzie ma swoje ograniczenia. Prowadzą one do kolejnego pytania: „jak tego użyć, aby zweryfikować daną funkcjonalność”. Presja projektu, konieczność dotrzymania terminu powoduje „doginanie rzeczywistości”, czyli takie zastosowanie automatu, które staje się jednorazowe. Jest to zupełnie niezgodne z przesłankami automatyzacji.

W jednej ze znanych gier FPS (strzelanki pierwszoosobowej), na postać żołnierza, w którą wciela się gracz, mówi się „operator” (analogicznie do wojskowej rzeczywistości). Moim zdaniem różnica pomiędzy terminem „żołnierz” a „operator” jest zasadnicza. Ten ostatni stwarza dystans do przedmiotu pracy. Żołnierz atakuje, broni się, wysadza. Operator używa karabinu, pistoletu lub materiałów wybuchowych. Jest to niuans, ale w zawodzie testera prowadzi on na manowce. Syndrom operatora jest jedną ze współczesnych przypadłości zawodowych. Bardziej skupiamy się na tym, jak użyć narzędzia, niż nad tym, jak z wykorzystaniem narzędzia zbudować testy. 

„Cudne manowce…”

Zawód testera podlega nieustannej ewolucji wewnętrznej, czyli rozwoju w dziedzinie testów, jak i zewnętrznej – przejściu do działów rozwojowych. W świecie testów ręcznych głównymi zagadnieniami są: jak działa system, jak powinien przetwarzać, jak zweryfikować to, czy dane się przetwarzają, czy integracja jest poprawna, jak zbudować zestaw danych, co otrzymam po przeprocesowaniu takich lub innych danych i tak dalej. Testowane oprogramowanie jest w tym przypadku jedynym fundamentem, na którym tester buduje swoje procesy weryfikacyjne. Powstające w tym procesie narzędzia są dedykowane rozwiązywaniu konkretnych problemów. Może niedoskonałe programistycznie, może skalowalne, ale w 100% wspierające pracę testera.

Jednocześnie inżynier testów staje się specjalistą i ekspertem w zakresie działania testowanego systemu. Daje to znakomity materiał na pracownika działów deweloperskich oraz pozwala na redukcję administracji testowej (np. spisywanie przypadków testowych, utrzymywanie dokumentacji). Wisienką na torcie jest fakt zastępowalności kompetencji, co przy bardziej złożonych systemach jest cechą nie do przecenienia. Kilkuosobowym zespołem o takich kompetencjach można w krótkim czasie weryfikować złożone platformy (np. w testach powdrożeniowych w trybie „wszystkie ręce na pokład”).

Metoda ta ma jednak swój punkt krytyczny, po którym przestaje być tak wydajna. Zwiększająca się liczba systemów oraz projektów na nich realizowanych wymaga zmiany podejścia. Zespoły testerskie zaczynają się zastanawiać nad strategią automatyzacji testów. Tutaj znaczenie ma bardzo wiele czynników: czy testujemy front-end, czy testujemy back-end, czy aplikacja jest tworzona przez zespół wewnętrzny, czy może dostarczana przez zewnętrznego dostawcę… Po podjęciu decyzji następuje wdrożenie wybranej platformy, a wtedy pojawiają się pierwsze symptomy „choroby operatora”.

Testerzy – będący z reguły ludźmi kreatywnymi i ciekawskimi – zmieniają punkt zainteresowania i pytają np. „jak zautomatyzować testy interfejsu ‘x’”, „jak dostosować funkcję automatu do moich potrzeb”, „jak wygenerować specyficzne requesty”. Pytania nie dotyczą już ani systemu, który jest do przetestowania, ani sposobu jego weryfikacji. Odnoszą się do narzędzi. Co więcej, samo narzędzie w sobie jest ciekawym obiektem do eksploracji: „a co się stanie, gdy  uruchomię to tak”, „a co robi ta funkcja” – w ten sposób tester oddala się od testów.

Dodatkowo zasobożerna automatyzacja stawia zupełnie nowe pytania o duże wolumeny danych testowych. A takie zestawy trzeba umieć definiować i także generować. W niektórych przypadkach jest to bardzo trudne i pochłaniające – szczególnie tam, gdzie dynamika zmiany jest ogromna.

Syndrom „testów spaghetti”

Testerzy zajmujący się automatyzacją dużą część czasu spędzają na rozmowach o repozytoriach, frameworkach, językach programowania, konkretnych implementacjach, generatorach i resource poolach. Pozostawmy programowanie programistom, a testowanie testerom.

Czy to znaczy, że testerzy mają się odgradzać od programistów? Absolutnie nie! Odwrotnie, powinni jak najwięcej się od nich uczyć. Głębiej wchodzić w ich świat ponieważ wszelkie znaki na niebie i ziemi pokazują, że testerzy i programiści będą pracować albo na tych samych środowiskach/procesach/zasobach, albo bardzo do siebie zbliżonych. Dodatkowo powinni szczególnie dbać o dobre relacje z programistami i dokładać wszelkich starań, aby integrować się z nimi. W każdej dyscyplinie sukcesy odnoszą zespoły, a nie pojedynczy ludzie. Co więcej, skomplikowanie dzisiejszych rozwiązań informatycznych wymaga wspólnych kompetencji (np. CI/CD, sztuczna inteligencja, release management, configuration management i tak dalej).

Każdy inżynier, borykający się z automatyzacją testów, zapewne zmierzył się z sytuacją, w której liczba automatycznych przypadków testowych była tak wielka, że rozsądniej, z perspektywy czasu, wydawało się napisać nowy, bardzo podobny przypadek niż wyszukiwać go w oceanie już funkcjonujących. Powoduje to utratę kontroli, która jest kluczowym czynnikiem w procesie weryfikacji. Zachowaniu jej służą różne techniki programistyczne, jak np. wzorce programowania, odpowiednia dokumentacja kodu czy umiejętność zbudowania repozytorium. Literatura przedmiotu pokazuje, że te zagadnienia nie należą do szkoły podstawowej dla programistów, więc jak tester ma sobie z tym poradzić?

Kontrola repozytorium jest trudna. Jej brak prowadzi do nadmiarowości testów i powstawania „testów spaghetti”. Zwłaszcza w przypadku scenariuszy regresyjnych, gdzie żelazny zestaw testów jest uruchamiany wielokrotnie. W takich wypadkach pokrywa się tylko zakres odpowiadający na pytanie o to, czy program robi to co miał robić w taki sposób w jaki miał robić.

W efekcie bardzo niechętnie usuwa się z takiego zestawu przypadki, w nieskończoność dodając nowe i/lub bardzo podobne do już istniejących. Przerabianie czyjejś pracy prowadzi do napisania własnego kodu, bo tak jest łatwiej. A przy skomplikowanych zestawach testowych trudno zorientować się, co właściwie robi dany zestaw skryptów. Może więc lepiej go nie ruszać i napisać własną wersję? Jest to oczywisty błąd testerski, ale bardzo poprawne zachowanie z perspektywy programistycznej – komuś roboty nie popsujemy, a zadanie zrealizujemy! Tylko czy rzeczywiście o to chodzi?

Przygotowanie takiego „spaghetti” jest nie tylko kosztowne. Jest także sprzeczne z podstawą zawodu testera, czyli z szukaniem sposobów na optymalną i wydajną weryfikację.

Kwestionowanie automatyzacji testów jest bezcelowe. Wszystko dzieje się w takim tempie, że nie ma innej alternatywy. Natomiast to, w jaki sposób testerzy podchodzą do automatyzacji, jest kwestią otwartą. Wchodzenie w buty programistów jest błędem z taktycznej perspektywy. Liderzy i osoby odpowiedzialne za kreowanie strategii testów i budowanie zespołów testerskich powinni kłaść szczególny nacisk na kompetencje testerskie, nie pozwalając tym zespołom uciekać w stronę programowania.

Zawód testera polega na umiejętności tworzenia rozwiązań, których celem jest weryfikacja i odpowiedź na dwa kardynalne pytania, które postawiłem na początku tego eseju. W przeciwnym wypadku czeka nas los operatora lub zjadacza rozgotowanego makaronu.

Przyszłość

Sztuczna inteligencja zapewne znacznie usprawni i jeszcze przyspieszy testy, szczególnie front-endowe. Już w tej chwili dostępne są systemy, pozwalające przygotować bardzo wydajny zestaw danych testowych. Kontrola elementów interfejsu WWW, print screeny i filmiki to klasyka. Podobnie technologia porównywania obrazów przez algorytmy sztucznej inteligencji. Wystarczy złożyć to w „orkiestrę”: przejść przez GUI, zweryfikować stan zero (np. na podstawie makiet lub prototypów), a następnie porównywać każde przejście ze stanem zero, modyfikując ten ostatni względem zmian wymagań.

Przyszłością testów i testerów jest mocniejsze wejście w procesy iteracyjne oraz monitoring. Na taki kierunek wskazuje dzisiejszy rozwój technologii: mikroserwisy, chaos design, chmura… Oznacza to konieczność ciągłego doskonalenia swojego warsztatu testera, ale także podążania za zmianami technologicznymi. Na niektórych poziomach technicznych będzie to absolutna konieczność, na innych znakomite usprawnieniem.

Zaangażowanie się, szczególnie w przypadku rozwiązań chmurowych, w procesy release managementu i szeroko rozumianego monitorowania także otwiera szerokie perspektywy testerskie.

Jak będzie wyglądał zawód testera oprogramowania za 20 lat? Czy w ogóle będzie istniał? Nie wiem i uważam takie rozważania za bezprzedmiotowe. Kiedy zaczynałem pracę w zawodzie, „HAL 9000” był wytworem literackiej wyobraźni, a telefon komórkowy przypominał cegłę. Dzisiaj mój smartfon opowiada suchary. Z całą pewnością można powiedzieć, że będziemy zalewani coraz większą liczbą narzędzi, które będą coraz bardziej skomplikowane w swojej strukturze, a coraz łatwiejsze w obsłudze. Tylko czy będziemy umieli odpowiedzieć na pytanie o to, „jak to działa” czy „dlaczego uzyskałem takie rezultaty”, testując je lub używając ich?

Liczę na większy rozwój narzędzi wspierających analizę testową. Wydaje się, że informatyka porzuciła formalizację wymagań tworzonych przez biznes, więc tym bardziej potrzebne są rozwiązania wspierające testera w korzystaniu z takich narzędzi, jak tabele decyzyjne, analiza domen, wartości brzegowe czy analiza przepływu.