Testowanie oprogramowania należy do podstawowych obowiązków każdego programisty. Testy możemy podzielić na dwa podstawowe rodzaje: automatyczne oraz manualne. Testy automatyczne polegają na tworzeniu skryptów testowych, które następnie mogą być uruchamiane bez naszej ingerencji - za ich tworzenie odpowiada przede wszystkim programista, choć czasami zdarza się również, że wspiera go przy tym dział Quality Assurance lub tester automatyzujący.
Z kolei testowanie manualne opiera się na ręcznym przechodzeniu przez konkretne ścieżki w naszym projekcie - za co odpowiada rozumiejący problem biznesowy tester manualny, którego zadaniem jest wykrycie warunków brzegowych oraz sprawdzenie najważniejszych przypadków użycia.
Wraz z transformacją większości świata tworzenia oprogramowania na metodyki zwinne (ang. agile) testowanie stało się chlebem powszednim każdego programisty. Skoro pracujemy w szybkim iteracjach i godzimy się na zmiany, to musimy mieć pewność, że nasz system jest niezawodny i zwraca oczekiwany wynik, a wprowadzane w nim nowe funkcje nie wpływają na inne fragmenty systemu (błędy tego typu określane są słowem regresja).
Trudno więc się dziwić, że Kent Beck jako pierwszy punkt na liście czterech zasad dobrego projektowania oprogramowania umieścił zdanie "kod musi przechodzić wszystkie testy". Żeby jednak testowanie kodu było wydajne, powtarzalne i deterministyczne - cały proces musi zostać zautomatyzowany. Chcąc zrobić to samo manualnie wszystko byłoby zbyt czasochłonny i zbytnio podatne na niedopatrzenia.
Ponieważ testowanie automatyczne pozwala na bezpieczne zmiany funkcjonalności jest integralną częścią pracy programisty. Co więcej - przygotowywnaie przypadków testowych pozwala na refleksję nad tworzonym rozwiązaniem i bardziej skuteczne wyszukiwanie warunków brzegowych. Niektórzy programiści piszą nawet testy zanim usiądą do implementacji kodu, testując początkowo pusty interfejs. Podejście takie znane jest pod nazwą Test Driven Development (w skrócie TDD). Wielu, a może i większość zespołów nie raportuje oddzielnie czasu poświęconego na testy, traktując je jako część integralną część swojego rzemiosła.
Skoro już wiemy, że automatyzacja testów to podstawa, to warto wspomnieć o kilku najważniejszych ich rodzajach, do których zaliczają się:
Wszystkie trzy tworzone są przez programistów. Współcześnie każdy język programowania posiada przynajmniej jedno rozwiązanie umożliwiające pisanie testów.
Oprócz nich warto wymienić dwa dodatkowe rodzaje testów. Pierwszymi z nich są testy E2E (end-to-end). Są one wykonywane z perspektywy użytkownika końcowego i nie wymagają znajomości języka programowania, w którym została napisana nasza aplikacja. W ostatnich latach powstało wiele narzędzi takich jak Playwright czy Cypress umożliwiających tworzenie testów automatycznych korzystających z przeglądarki, które pozwalają tworzyć rzeczywiste scenariusze testowe.
Podejście to ma dwie podstawowe wady - są one dość wolne, i często w zbyt dużym stopniu zależą od interfejsu, przez co przy ich nieoptymalnym zaprojektowaniu zmiany graficzne będą wymuszać ich zmianę.
Innym rodzajem testów są testy obciążeniowe, których celem jest sprawdzenie, czy nasze rozwiązania obsłuży prognozowany ruch oraz jak zachowa się przy nagłym jego wzroście. W wielu przypadkach niezawodność decyduje o powodzeniu lub nie projektu, dlatego nie powinniśmy ich pomijać.
Drugi wariant stanowi podejście manualne, w którym dana osoba ma ręcznie przetestować funkcje systemu. Testowanie manualne w branży IT ma nieco burzliwą historię, bo programistom kojarzy się z kierownikami projektów, którzy goniąc terminy wymuszali na nich rezygnację z tworzenia testów automatycznych. W teorii miało to przyśpieszyć pracę, ale ostatecznie ją zwalniało oraz wprowadzało wiele trudnych do wykrycia błędów ludzkich. W końcu nie ma nic bardziej zawodnego od czynnika ludzkiego, a wykonując po raz n-ty te same powtarzalne zadanie w końcu coś przeoczymy.
Nieco inaczej sytuacja wygląda w przypadku dedykowanych testerów oprogramowania. Powinni oni jednak dobrze poznać biznes klienta zlecającego aplikację, ponieważ ich celem nie jest szukanie błędów prostych do wykrycia przez testy automatyczne (to jest domena programistów), ale wyłapanie przegapionych warunków brzegowych oraz upewnienie się, że reguły biznesowe zostały poprawnie odwzorowane.
Wszystkie opisane przez nas rodzaje testów wzajemnie się uzupełniają i często warto korzystać ze wszystkich z nich, ale nie jest to regułą.
W przypadku testów automatycznych (jednostkowych i integracyjnych) stanowią one podstawę pracy programisty i pod żadnym pozorem nie powinniśmy próbować rezygnacji z nich dla pozornego zysku czasowego, bo efekt zawsze jest odwrotny od oczekiwanego.
Testy E2E (end-to-end) są bardziej czasochłonne i zasobożerne, więc warto pokrywać nimi najważniejsze scenariusze w naszym systemie (takie jak zakładanie konta czy realizacja zamówienia). Warto znać wady i zalety tego rozwiązania, aby nie przesadzić.
W przypadku testowania manualnego celem testera jest upewnienie się, że aplikacja działa zgodnie z oczekiwaniami biznesowymi. Tester manualny nie powinien zastępować jednak testera automatyzującego i sprawdzać elementów, które powinny zostać wykryte na podstawie testów automatycznych.
Testy wydajnościowe warto wprowadzać w przypadku systemów, dla których możemy oczekiwać wzmożonego ruchu (jeśli wiemy, że z naszej aplikacji będzie korzystać 15 osób, to testy takie wiele nam nie powiedzą).
Cześć! Nazywam się Artur Kędziora i jestem jednym z założycieli firmy Southern Sun. Z chęcią opowiem Ci więcej o naszej ofercie i rzeczach, które możemy wspólnie zrobić.