Jak testować oprogramowanie? 7 zasad testowania dla programisty

948
views

Po co testować oprogramowanie

Dzisiaj zdecydowanie lżejszy temat na tapecie – po co właściwie testować oprogramowanie. Czy nie jest przypadkiem to przerost formy nad treścią? Po co komu cały zespół testerów w projekcie, te całe testy – jak przecież teraz pisze się w oparciu o TDD i wszystko musi działać by test przeszedł. Czy to nie załatwia sprawy? Otóż nie do końca i trochę Wam o tym opowiem.

Jak to jest z tymi błędami?

Oprogramowanie to już jest nieodzowny element naszego życia. Aktualnie nie tylko komputery “mają” oprogramowanie ale i telefony, telewizory, samochody i wiele innych aspektów życia codziennego. Przypomniał mi się nawet ten żart o programowaniu pralki – możemy się śmiać ale to aktualnie fakt, teraz nowsze modele pralek mają wbudowane oprogramowanie dzięki któremu możemy za pomocą telefonu uruchomić pranie, zdalnie. Obecna technologia poszła tak naprzód, że z poziomu telefonu jesteśmy w stanie otworzyć samochód, zapalić mu światła czy namierzyć jego lokalizację. Jeszcze parę lat temu to co było nie do pomyślenia jest codziennością. Komputery, oprogramowanie otaczają nas z każdej strony i nie da się chyba tego już uniknąć – no chyba, że wyjdziemy na drugi koniec świata i tam zamkniemy się w dżungli.

Nie mniej, przypomnij sobie drogi czytelniku ile razy aplikacja, czy ta w telefonie, czy na komputerze, wywinęła Ci numer i się zawiesiła, albo zrobiła coś czego się nie spodziewałeś, albo strona nagle sypnęła zdecydowanie moim ulubionym błędem jakim jest 500 Internal Server Error. Z pewnością nie jeden raz, prawda? I raczej przyjemne to nie było, bo chyba tylko tester potrafi cieszyć się z 500tki na ekranie 😉 Prawda jest taka, że w najlepszym wypadku tracimy czas (na przykład by ponownie wypełnić formularz, albo musimy poczekać aż błąd zostanie naprawiony), często pieniądze (ostatnio była dosyć głośna awaria systemu płatności kartą, gdzie z konta były pobierane pieniądze, a transakcje nie dochodziły do skutku) a nawet zdrowie czy życie.

W wielu książkach o testowaniu można spotkać się ze stwierdzeniem, że oprogramowanie zwykle ulega awarii przez usterki wynikające z pomyłek programistów. I śmiem się z tym nie zgodzić. To prawda, programiści popełniają błędy, tak… tak samo jak testerzy, analitycy biznesowi i cały sztab innych osób biorących udział w procesie tworzenia oprogramowania. To, że “bug” wychodzi spod palcy programisty, nie zawsze znaczy, że jest on temu winny.

Każdy człowiek popełnia błędy, z różnych przyczyn. Czasem wynika to ze złożoności kodu, czasem z roztargnienia, stresu, presji czasu, czy słabej znajomości zastosowanej technologii. Można tak długo wymieniać i wymieniać. Każdy ma prawo popełniać błędy… każdy program może zawierać (i z pewnością zawiera) usterki i tu wchodzę ja (jak to leciało? ubrana cała na czerwono?) – tester. Tester nie sprawi, że nagle wszystkie usterki zostaną znalezione (choć pewnie każdy by tak chciał), ale dobrze zaplanowane i przeprowadzone testy spowodują, że zmniejszy się ryzyko ich wystąpienia.

Kilka słów o samym testowaniu

A teraz pomyślmy, co przychodzi nam pierwsze do głowy gdy mówimy słowo testowanie. Mi przychodzi do głowy słowo, sprawdzenie, sprawdzenie czy coś działa tak jak tego oczekujemy. I tak naprawdę testowanie tym jest – z jednym tylko detalem – samo sprawdzenie czy działa – jest jednym z kilku etapów. Bo zarówno przed tym jak i po muszą być wykonywane inne działania. Wszystkie te czynności nazywamy procesem testowym.

Proces może mieć fazy takie jak: planowanie, analiza, projektowanie, implementacja, wykonanie, ocena wyników, zamykanie czynności testowych. W rzeczywistości w różnych normach (np IEEE czy ISO) czy źródłach (ISTQB) możemy znaleźć różnie nazwane fazy procesów testowych – chociaż sprowadzają się do tego samego.

Testujemy głównie po to by znaleźć błędy w oprogramowaniu, ale nie tylko. Testowanie również, powinno dawać nam odpowiedzi na pewne pytania np. czy aplikacja nadaje się do udostępnienia klientowi.

Na każdym etapie projektu cel testów może się różnić od siebie, na przykład w początkowej fazie – zwykle testerom zależy na znalezieniu jak największej liczby błędów i zwykle tak się dzieje. W końcowej fazie, zwykle zależy nam na upewnieniu się, że wszystko działa jak powinno i aplikacja jest zgodna z wymaganiami.

7 zasad testowania, które powinien znać programista

Chyba każdy tester, na początku swojej drogi spotka się w literaturze z tymi siedmioma podstawowymi testowania. Warto by znali je również programiści, mogą wydawać się czasem oczywiste, jednakże ich znajomość może pomóc całemu zespołowi w tworzeniu jeszcze lepszego produktu.

1. Testowanie ujawnia błędy

Jakkolwiek prosto to nie brzmi, to testowanie ma ujawniać usterki a nie ich brak. Jeżeli QA podczas wykonywania testu, otrzyma wynik inny od zakładanego – oznacza to, że istnieje jakiś problem. Problem ten może dotyczyć programu jak i dokumentacji. I wtedy należy przeprowadzić analizę problemu i odpowiednio raportować

Co jeśli nasze testy nie zwrócą błędów? Czy to znaczy, że nasze oprogramowanie jest idealne? Nie, przypomnij sobie z poprzednich artykułów jak duży wpływ mają dane testowe i stworzone przypadki testowe. W aplikacji może istnieć błąd którego nasze testy nie wykryły. Oczywiście testowanie redukuje ryzyko wystąpienia błędów ale nie jest dowodem na to, że aplikacja jest wolna od defektów.

2. Nie da się przetestować wszystkich możliwych kombinacji

Mając nawet najlepszego testera na świecie, nie da się przetestować wszystkich możliwych kombinacji. No dobrze, da się. ale w bardzo ale to bardzo trywialnych warunkach. W poprzednim artykule podałam przykład z loginem i hasłem – i to tylko w wersji brak, poprawne, niepoprawne a tych kombinacji było sporo. Chcąc to jeszcze rozbić na bardziej szczegółowe przypadki np. wpisano niepoprawny email bez znaku “@” to liczba przypadków jeszcze bardziej się zwiększy. A co dopiero w złożonej aplikacji gdzie istnieje bardzo wiele zależności i alternatywnych rozwiązań.

3. Im szybciej zaczniemy proces testowy tym lepiej

Proces testowy trzeba rozpocząć tak szybko jak się da. Tak naprawdę proces testowy powinien się rozpocząć na etapie analizy wymagań. Nawet jeśli jeszcze ani jedna linijka kodu aplikacji nie została napisana przez programistów. Test plan czy pierwsze przypadki testowe mogą być pisane jeszcze w początkowym etapie, gdy zespół analizuje wymagania dotyczące aplikacji.

Zastanawiacie się dlaczego? Przecież na samym początku projektu, gdy dopiero wyłania się szkielet aplikacji, QA może zająć się tym wszystkim… teoretycznie tak, ale w praktyce – jeśli tester w pełni poświęci uwagę na szukanie błędów od samego startu projektu, szybciej zostaną wykryte i naprawione. Kluczowym faktem jest tutaj fakt, że analizy pokazują, że koszt naprawy błędu rośnie w czasie. To znaczy – jeśli znajdziemy i naprawimy błąd na etapie wczesnego developmentu – będzie on kosztował firmę mniej niż naprawianie tego samego błędu na produkcji. Dlatego nie warto odkładać fiksowania błędów na później.

4. Błędy lubią się kumulować

Ilość poświęconej pracy jaka powinna być włożona w cały proces testowy powinna być proporcjonalna do spodziewanej / obserwowanej liczby błędów w różnych częściach aplikacji. To mówią zwykle podręczniki do testowania, co to oznacza dla nas w praktyce? W testowaniu obowiązuje tzw. zasada 80/20 – to znaczy 20% przyczyn odpowiada za 80% skutków czyli w przypadku testowania można powiedzieć, że 80% błędów znajduje się tylko w 20% modułów całej aplikacji.

Błędy kumulują się w jednym miejscu. Jeżeli tester dobrze zna aplikację, dobrze zorganizował proces testowy, sprawnie znajdzie te części aplikacji które wymagają większej uwagi (na przykład raporty wykażą, że w jednym module jest więcej błędów niż w innych). W ten sposób prawdopodobnie sprawnie, wykryjemy sporą liczbę usterek.

5. Paradoks pestycydów

W testowaniu obowiązuje tak zwany paradoks pestycydów, który mówi o tym, że stosowanie pestycydów których zadaniem jest pozbycie się szkodników może spowodować ich namnażanie się. Ja bym to bardziej porównała do bakterii, i antybiotyków. Bakterie w pewnym momencie są w stanie uodpornić się na dany antybiotyk, który przestaje na nie działać. Podobne zjawisko zachodzi podczas testowania i jest związane ze skutecznością testów. Jeżeli będziemy wykonywać tylko i wyłącznie te same testy bez żadnych zmian – nasze testy przestaną wykrywać błędy. Aby uchronić się przed tym zjawiskiem – testy, zestawy testów i przypadki testowe powinny być regularnie sprawdzane i modyfikowane.

6. Ważny jest kontekst

NIe da się raz ustalić i potem tylko stosować jeden dokładny proces testowy. Każdy przypadek, projekt jest inny. Różne czynniki mają wpływ na jego kształt. Inaczej będziemy testować aplikację mobilną, inaczej webową jeszcze inaczej aplikację opartą o Machine Learning. Inne podejście należy zastosować do aplikacji dedykowanej dla ograniczonego grona użytkowników a inaczej aplikację szeroko dostępną, którą każdy może w każdej chwili pobrać z internetu i jej używać. Wszystkie decyzje dotyczące kształtu procesu testowego zależą od kontekstu. Ilość, rodzaj czy poziom testów jest różny. Ponadto czasami umowy z klientami zobowiązują nas w umowie do przeprowadzenia testów w określonych warunkach.

Czasem wystąpienie błędu na produkcji ma jakiś próg akceptowalności, to znaczy, aby być konkretnym – błędy na produkcji nigdy nie są pożądane ale jeśli użytkownikowi nie wyświetli się reklama na dole strony to jest to błąd który w określonych warunkach może być dopuszczalny ale już na przykład w aplikacji którą używa kontroler lotów, brak komunikatu o dwóch samolotach na kursie kolizyjnym – może mieć skutki katastrofalne.

W dodatku, procesy testowe będą wyglądały inaczej w przypadku projektów prowadzonych w Scrumie, a inaczej w zwykłym waterfallu. To że dany proces sprawdził się w przypadku aplikacji A nie oznacza, że sprawdzi się przy aplikacji B. Trzeba być bardzo uważnym a zarazem elastyczny. Dlatego tak trudne jest zdefiniowanie dobrego procesu testowego, tak by spełniał wszystkie pokładane w nim oczekiwania.

7. Fałszywe przekonanie o braku błędów

Użytkownika końcowego aplikacji zwykle nie interesują wyniki testów, albo jakie testy zostały przeprowadzone. Dla użytkownika końcowego zwykle najważniejsze jest jedno – ma działać. Ostatnio będąc u lekarza, miałam okazję być pierwszą pacjentką tego dnia. Więc pani doktor musiała uruchomić urządzenie, na komputerze uruchomić aplikację która zbierała wyniki i je analizować. Pech chciał że aplikacja nie potrafiła połączyć się z urządzeniem, które “jeszcze wczoraj normalnie działało”. Przez ponad pół godziny trwała walka o to by badanie mogło dojść do skutku. Na zewnątrz kolejka sfrustrowanych pacjentów czekających na badanie rosła, kobieta była zestresowana ze nie działa a powinno. Dopiero po całkowitym resecie wszystkiego – aplikacja ożyła i było możliwe przeprowadzanie badania.

Ta pani miała tylko jedno oczekiwanie – by w końcu to zadziałało i mogła wykonać swoją pracę. Nawet jeśli przeprowadzimy milion testów, stworzymy piękne raporty z testów – nie mamy gwarancji, że produkt spełnia oczekiwania i wymagania użytkowników. Bo co z tego jak aplikacja po prostu nie będzie działać wtedy kiedy ma, albo będzie zupełnie nieużyteczna? Zawsze podczas testowania należy pamiętać, że ta aplikacja nie jest robiona dla nas – ona jest dla użytkowników.

I jeszcze raz o ilości testów

Jak sobie już wcześniej wyjaśniliśmy – tester nie jest w stanie przetestować wszystkiego. W jaki sposób w takim razie podjąc decyzje o rodzau testów, ilości czy ich zakresie? Kiedy będziemy wiedzieć, że to jest ten moment w którym można wydać aplikację? Tutaj z pomocą przychodzi nam priorytetyzacja. Jeśli uszeregujemy testy od takich które muszą być wykonane w pierwszej kolejności (bo na przykład błędy w tych częściach aplikacji niosą ze sobą największe ryzyko) do takich które mogą być wykonane później. Dzięki temu nawet jeśli z jakiegoś powodu będziemy musieli wcześniej skończyć testy – kluczowe części aplikacji będą przetestowane

Kolejnym elementami, które mogą dać nam odpowiedź na to czy możemy już skończyć testy są metryki. Możemy mierzyć niezawodność systemu, liczbę znajdowanych defektów, defekty zgłoszone vs. defekty naprawione, stopień pokrycia wymagań, kodu itp itd. Metryki mogą posłużyć nam jako warunki kryterium wyjścia czyli warunki zakończenia testów.

Podsumowanie

Wszystko to dobrze brzmi – ale pytanie – co z tego może wynieść programista? Jakie, korzyści? Jaką wiedzę? Po pierwsze programista też może wyciągnąć informacje dla siebie z procesu testowania. Tutaj z pomocą mogą przyjść metryki. Jeśli zespół testerski, bądź tester dobrze zdefiniuje metryki, dobrze zaplanuje proces testowy, programista dostanie, można powiedzieć namacalną informację o jakości oprogramowania.

Jeśli w trakcie procesu testowania znajdujemy relatywnie mało błędów może to świadczyć o dwóch rzeczach, wysokiej jakości oprogramowania, albo o złym procesie testowym. Jeśli to drugie wykluczymy, poprzez dobre zaplanowanie testów, przypadków testowych (o nich możesz poczytać tutaj) itp itd. możemy przypuszczać, że stworzyliśmy coś o dobrej jakości.

Świadomość programistów po co się testuje, jakie testowanie ma cele oraz jakimi zasadami rządzą się testy czy świadomość zagrożeń jakie czyhają na cały zespół developerski (np. paradoks pestycydów) będzie mieć z pewnością bezpośredni, korzystny wpływ na projekt.