Testuj przed wszystkimi, czyli shift-left testing w praktyce

Mariusz Skomra | Rozwój oprogramowania / Zarządzanie projektami | 25.08.2021

Czym jest podejście „shift-left testing”? Zobacz, jak korzystamy z niego w praktyce, jakie przynosi korzyści, a także jakie okoliczności sprawiły, że jest ono możliwe do zastosowania.

Scrum czy Scrumfall?

W klasycznych metodykach wytwarzania oprogramowania, takich jak Waterfall, proces testowania oprogramowania następuje po fazie jego zaprojektowania i wytworzenia. Tym samym obiektem poddawanym testowaniu jest gotowy, ostateczny produkt. Głównymi problemami, jakie to rodzi, są długi czas naprawy błędów, ich wysoki koszt, a także ryzyko, iż wprowadzone zmiany wpłyną na inne funkcjonalności (co z kolei niesie za sobą konieczność ponownego wykonania wszystkich testów, a tym samym wydłużeniu ulega cały proces).

W ostatnich latach state-of-the-art w wytwarzaniu oprogramowania są tzw. metodyki zwinne (Scrum, Kanban itp.). Dzięki iteracyjnemu podejściu procesowi testowania nie jest poddawany cały, gotowy produkt, lecz jego fragmenty będące rozwinięciem poprzedniej wersji, niebędące jednak jego ostateczną wersją.

Niestety, niepoprawne wdrożenie metodyk zwinnych również niesie ryzyko powtórzenia powyżej opisanych błędów. Przykładem niech będzie jeden z moich wcześniejszych projektów, gdzie w czasie trwania Sprintu był wyraźny podział na fazę omawiania zadań, development, a następnie testowanie. Czym się kończył taki Scrumfall pod koniec Sprintu?

  • Testerzy mieli mało czasu na wykonanie testów (bo development zadania się przedłużył),
  • Developerzy mieli mało czasu na wykonanie ewentualnych poprawek (bo testerzy potrzebowali czasu na testy),
  • Product Owner sugerował, aby niekiedy przymknąć oko na testy (bo trzeba oddać, a przetestować można później),
  • Klient zastanawiał się, czy testerzy są potrzebni na cały etat (bo przecież w pierwszym tygodniu Sprintu nic nie robią).

Dodatkowo dochodziło do sytuacji, gdzie na etapie testowania okazywało się, że developer zrozumiał zadanie w jeden sposób, tester w drugi, a klientowi chodziło o coś zupełnie innego. Tym samym zadanie, które było uznawane za „prawie skończone” stawało się zadaniem „do omówienia” (co wydłużało proces jego dostarczenia).

Shift-left – co to takiego?

Nie tylko błędne zrozumienie Agile w organizacji może zwiększać ryzyko niepowodzenia w projekcie. Problem planowania czasu na testy oprogramowania pojawia się w wielu projektach bez względu na stosowaną metodykę. Okazuje się jednak, że istnieje podejście, które może być jeśli nie „lekiem na całe zło”, to na pewno środkiem łagodzącym objawy nieumiejętnego rozplanowania prac w projekcie. Mowa tu o shift-left testing. To podejście mówiące o tym, żeby proces testowania zaczynać na jak najwcześniejszym etapie wytwarzania oprogramowania.

Przejdźmy teraz przez wszystkie etapy  wytwarzania oprogramowania i odpowiedzmy sobie na pytania:

„Czy to jest wystarczająco wcześnie na testy? A jeżeli nie, to dlaczego?”.

Środowisko produkcyjne

Pytanie o testy na produkcji zawsze jest dyskusyjne i niejednokrotnie prowadzi do odpowiedzi: „To zależy”. Czy warto testować na tym etapie? Moim zdaniem tak. Jednakże mówimy tu wówczas o tzw. smoke testach. Za ich pomocą sprawdzamy jedynie, czy kluczowe ścieżki działają. Szczegółowe testy powinny zostać wykonane na wcześniejszych etapach – o ile jest to możliwe. Kiedy nie jest? Przykładowo: serwis należy do zewnętrznego dostawcy i na niższych środowiskach jest on mockowany. Kolejny przykład: wysyłamy zapytanie do innego serwisu, którego baza produkcyjna jest 1000-krotnie większa niż na środowisku testowym (kilkanaście milionów obiektów vs kilkanaście tysięcy), co znacząco wpływa na rozmiar otrzymywanych danych i ich liczbę. Jeszcze innym przykładem testów na produkcji mogą być np. testy konfiguracji. W jednym z projektów dostaliśmy zadanie, aby zmienić sposób budowania aplikacji. Z poziomu użytkownika nic się nie zmieniło. Dla zespołu developerskiego zmieniło się wszystko, gdyż wdrożone zostało nowe narzędzie wraz z nową konfiguracją. Dodatkowo okazało się, że jego konfiguracje nieco różniły się na każdym ze środowisk.

Środowisko testowe

Środowisko testowe to środowisko starające się odzwierciedlić w jak największym stopniu środowisko produkcyjne. Wykonujemy na nim testy regresji (w postaci testów automatycznych uruchamianych co noc), które mają nie tylko sprawdzić jak najszerszy zakres funkcjonalności naszej usługi, ale też jej integrację z innymi serwisami. Takie podejście pozwala nam upewnić się, że najnowsza wersja aplikacji może być wydana na produkcję. Jednakże ten etap procesu wytwarzania również nie jest najwcześniejszym, na jakim wykonujemy testy. Traktujemy go bardziej jako element  pewnego rodzaju „double check”, dodatkowego sprawdzenia zmiany. Takie podejście wynika z faktu, iż proces naprawy błędu zajmuje sporo czasu ze względu na konieczność stworzenia nowej wersji kodu z poprawką, poddania jej procesowi code review, scalenia oraz wydania nowej wersji aplikacji.

Środowisko developerskie

To środowisko wykorzystywane jest przez developerów podczas codziennego wytwarzania oprogramowania. Charakteryzuje się tym, iż wdrożona na nim wersja aplikacji może zmieniać się bardzo często (nawet kilkukrotnie w ciągu dnia) oraz tym, iż nie musi ona działać poprawnie (stabilnie). Jednakże właśnie ze względu na bardzo krótki czas wdrażania zmian jest to również wyśmienite miejsce do przeprowadzania testów funkcjonalnych (zarówno wstępnych, jak i całościowych) oraz zgrubnych testów regresji. Dzięki testom na tym środowisku, jako tester, w bardzo krótkim czasie jestem w stanie powiedzieć, czy dana wersja  może wejść na środowisko testowe, czy jednak wymaga zmian. Niekiedy zmiany te wprowadzane są niemalże w czasie rzeczywistym – developer obserwuje zachowanie aplikacji podczas testów, analizuje przyczynę problemu, wprowadza poprawkę, a następnie wykonywany jest retest, który sprawdza, czy wszystko działa. Takie podejście zdecydowanie skraca czas otrzymania informacji zwrotnej od testera. Skraca również proces code review, ponieważ oddawany kod działa tak, jak powinien, i nie trzeba go modyfikować celem poprawy błędów (co tylko wydłużyłoby jego przegląd).

Analiza biznesowa i ustalanie wymagań

Czy można testować dokumentację bądź wymagania biznesowe? Oczywiście! Bardzo często spotykam się z sytuacją, kiedy ustalane są cele zadań i ich zakres, wszyscy mówią, że rozumieją i wiedzą, co ma być zrobione, po czym padają pytania: „A czy to nie wpływa na inny obszar aplikacji?”, „A czy ta logika na pewno jest zgodna z wymaganiami innych serwisów?”, „A czy wiemy, skąd te dane mamy pobrać?”, „A czy mamy makiety i tłumaczenia tekstów?”. I nagle okazuje się, że zadanie, które już zostałoby wzięte w zakres Sprintu – jest z niego usuwane lub zostaje zablokowane celem dalszych wyjaśnień. Gdyby nie to, to bardzo prawdopodobna  byłaby sytuacja, w której te pytania zostałyby zadane już w trakcie developmentu. A to skutkowałoby przedłużonym czasem rozwoju oprogramowania lub nawet niedostarczeniem funkcjonalności.

Czy można testować jeszcze wcześniej?

Wydawać by się mogło, że określanie wymagań biznesowych to najwcześniejszy etap procesu wytwarzania oprogramowania, w którym możliwe są testy oprogramowania. A co za tym idzie – nie da się przesunąć testowania bardziej w lewo. Otóż… nie jest to do końca prawda. Na konferencji TestWarez 2019 Marcus Merrell w swoim wystąpieniu „Shift Left, Shift Right – Why These Buzzwords Matter” powiedział, że kolejnym przesunięciem testowania na wcześniejszy etap jest… środowisko produkcyjne. Ale jak to? Testowanie na produkcji? Otóż nie testowanie, a monitorowanie. A następnie wyciąganie wniosków i tworzenie na ich podstawie nowych zadań mogących usprawnić działanie systemu.

Przykładowo: w naszym projekcie jedną z metryk, jakie zbieramy i analizujemy, jest rodzaj błędów biznesowych występujących w aplikacji. Gdy któryś błąd zaczyna się pojawiać dużo częściej, badamy, co jest jego przyczyną, i zastanawiamy się, co możemy zrobić, aby zredukować jego występowanie.

Shift-left testing – co nam to daje?

Najbardziej oczywistą i podkreślaną przez wszystkich zaletą podejścia shift-left testing jest wykrycie błędów na wczesnym etapie developmentu. Niemniej podejście to, w projekcie, jaki realizujemy w Inetum dla klienta z obszaru e-commerce, przynosi też inne zalety. Oto one:

Wczesna automatyzacja

W dyskusjach o automatyzacji testów bardzo często pojawia się pytanie: „Kiedy zacząć automatyzować?”. Moja odpowiedź zawsze brzmi: „Jak najwcześniej”. Przykładowo – zadanie polega na wprowadzeniu nowego pola do formularza oraz dodaniu nowych walidacji. Czy muszę czekać, aż developerzy przygotują backend i frontend, abym mógł zacząć testować manualnie, a następnie stworzyć testy automatyczne? Nie. Na podstawie opisu zadania tworzę przypadki testowe, jakie będą wykonane, wybieram te, które zostaną zautomatyzowane, a następnie przygotowuję kod testów. W efekcie, kiedy developer oddaje mi zadanie do testów, bardzo często wystarczy, że uruchomię taki kod i w bardzo krótkim czasie dostanę informację, czy funkcjonalność działa zgodnie z założeniami, czy nie (niekiedy wręcz nie muszę wykonywać testów manualnych, ponieważ automatyczne pokryją wszystkie przypadki, a na dodatek będą szybsze i dokładniejsze).

Podwójne sprawdzenie

Automatyzacja na wczesnym etapie niesie ze sobą dodatkową zaletę, jaką jest podwójne sprawdzenie funkcjonalności. Tzn. zmiana testowana jest na środowisku developerskim, kod jest scalany, nowa wersja aplikacji jest wydawana i wgrywana na środowisko testowe. Przygotowane testy automatyczne mają dać takie same wyniki na obu środowiskach. Czy tak się dzieje? Zazwyczaj tak. Niestety, w projektach zdarzały się sytuacje, kiedy jednego dnia scalonych zostało kilka różnych zmian, co w efekcie spowodowało niepoprawne działanie już przetestowanych funkcjonalności. Na szczęście codzienne uruchamianie testów pozwoliło nam na szybkie wykrycie tego problemu i jego poprawę.

Większa świadomość znaczenia testów

W dzisiejszym świecie bardzo często podkreśla się znaczenie testów w procesie wytwarzania oprogramowania. A jak jest naprawdę? Różnie. Pokuszę się o stwierdzenie, że co zespół, to inne podejście. W moim obecnym projekcie początkowo tryb pracy był… typowy tzn. developer zaczynał pracę nad zadaniem, przygotowywał zmianę, kod przechodził proces code review, wydawana była nowa wersja aplikacji i zadanie przechodziło w etap testów. Po kilku miesiącach pracy ten proces się znacząco zmienił. Wypracowaliśmy podejście, w którym przed przesunięciem zadania do code review kod jest sprawdzany przez QA.

Shift-left – dlaczego u nas działa?

Czy podejście shift-left zadziała zawsze i w każdym zespole?

Moim zdaniem nie. Dlaczego u nas się sprawdza? Jest kilka powodów:

  1. Wszystkie osoby tworzą zespół developerski. Nie mamy sytuacji, w których np. zespół dostaje zadania do wykonania bez wcześniejszych konsultacji czy testerzy i developerzy tworzą osobne zespoły bez bieżącego kontaktu ze sobą. Każdy ma wygląd w zadania i może zgłosić swoje uwagi na każdym etapie pracy.
  2. Odpowiednia infrastruktura. Jako zespół developerski nie musimy angażować swojego czasu w tworzenie infrastruktury, środowisk itp. Wszystko to przygotowywane jest przez osobny, dedykowany do tego zespół. My zgłaszamy zapotrzebowanie na zasoby, a następnie dostajemy działające rozwiązania.
  3. Dojrzałość zespołu. Zespół tworzony jest przez osoby, które mają doświadczenie w pracy zarówno w dobrze zorganizowanych projektach, jak i takich, które nie mogą zostać określone tym mianem. Tym samym wszelkie nasze doświadczenia („Wtedy robiliśmy tak i tak, i to powodowało, że mieliśmy problemy z tym i tamtym”) pozwalają nam teraz ustalić dużo lepszy proces developmentu i testowania. Dodatkowo wiemy, że swoboda naszego działania jest akceptowana, póki dostarczamy produkt wysokiej jakości. Dlatego też wszystkim zależy, aby błędy wykrywane były jak najszybciej.