Często spotykam się z niepoprawnym nazywaniem testów wykonywanych w procesie wytwarzania oprogramowania. Tym wpisem chciałbym przedstawić Ci siedem podstawowych typów testów. Mam nadzieje, że będziemy od teraz porozumiewać się tą samą terminologią (przynajmniej jeżeli chodzi o testy).
Testy w Inżynierii Oprogramowania
Testy jednostkowe (unit testing)
Testy stworzone przez autorów kodu, które testują pojedyncze funkcje. Czasami można pod tą definicje zalicza się także klasa.
Bardzo lubię pisać testy jednostkowe, ponieważ po ich napisaniu dla danej funkcji, mam pewność poprawności jej działania (przynajmniej dla przetestowanych przypadków). Podnosi to mój komfort podczas pracy twórczej (implementacji).
Każdy z testów powinien być uruchomiony w izolowanym środowisku. Co to oznacza? A no tyle że wynika działania jednego testu NIE MOŻE wpływać na drugi. W tym miejscu warto poznać mocki.
Narzędzia
Jakich narzędzi używam do pisania testów jednostkowych?
Bardzo lubię składnie i idee, które są zaaplikowane w bibliotece Jasmine ale też Mocha świetnie się spisuje jako test runner.
Pół roku temu stworzyłem na GitHubie projekt, gdzie wykorzystałem Jasmine oraz transpiler Babel - https://github.com/piecioshka/test-jasmine-babel. Niestety projekt ten nie zawiera większej definicji testów - nie ma punktu odniesienia. Jest on zrobiony tylko w celu udowodnienia (samemu sobie), że można wykorzystywać Babel.js, aby tworzyć testy.
Projekt opisany poniżej już może bardziej zaciekawić.
Dobrym przykładem z większą ilością testów jest biblioteka
https://github.com/piecioshka/super-event-emitter.
Na dzień 2016-04-16 W katalogu test/unit/specs/ ich liczba wynosi 32.
Ci z Was, którzy nie tworzyli wcześniej testów, to jest to najlepszy moment, aby w swoim projekcie (tak naprawdę w dowolnym) spróbować napisać kilka testów jednostkowych.
Pokrycie kodu (code coverage)
Podczas pisania testów jednostkowych ważne jest tzw. pokrycie kodu. Mam tutaj na myśli, stosunek procentowy: ile linijek kodu aplikacji zostało uruchomionych podczas testów do całości kodu. Jeśli coś zostało uruchomione, to TAK JAKBY zostało przetestowane.
Warto napisać kilka asercji to każdego wyrażenia, które coś modyfikuje.
Wskaźnik pokrycia kodu na poziomie 100%, mówi, że cały kod aplikacji został uruchomiony podczas testów, ale proszę nie mylcie tego z tym, że każda linijka została przetestowana.
Testy integracyjne (integration testing)
Testy stworzone przez developerów. Zweryfikowane są połączenia między modułami.
Testy integracyjne to trudniejszy temat. Tutaj pojawia się stworzenie sztucznego (laboratoryjnego) środowiska, gdzie takie testy można uruchomić.
Narzędzia
Podobnie jak w przypadku testów jednostkowych możemy wykorzystać te same narzędzia, aczkolwiek będziemy potrzebowali sprawdzić nie tylko poprawne działanie pojedynczej funkcji, ale połączenie jej z inną.
Testy end-to-end (e2e testing)
Testy stworzone przez developerów. Testują one procesy biznesowe w sposób emulujący zachowanie użytkownika. Celem jest przejście przez dowolny proces z logiki biznesowej w celu potwierdzenia poprawnej implementacji.
Najczęściej aby przeprowadzić testy E2E należy posiadać realistyczne dane. Przykładem niech będzie posiadanie loginu i hasła testowego konta, aby przetestować mechanizm logowania użytkownika (nigdy prawdziwych danych użytkowników).
Narzędzia
Ostatnio chętnie używam narzędzia Nightwatch.js. Testy piszemy w nim w kodzie, jako scenariusz kroków, które wykonałby tester (otwórz stronę, kliknij, sprawdź tekst).
Najpopularniejsze narzędzie do takich testów nosi nazwę Selenium. Nightwatch.js sam korzysta z protokołu WebDriver, na którym opiera się Selenium, ale dla nas (developerów JavaScriptu) jest wygodniejszy, ponieważ testy tworzymy w języku, którego używamy na co dzień. Nagrywanie scenariusza i jego automatyczne odtwarzanie oferuje z kolei Selenium IDE.
(Aktualizacja 2026: dziś do testów E2E sięgnąłbym po Playwright.)
Testy funkcjonalne (black-box testing)
Testy, które sprawdzają, czy aplikacja robi to, czego oczekuje użytkownik, bez zaglądania do kodu (stąd “czarna skrzynka”). Najczęściej przeprowadzają je osoby z zewnątrz (nie autorzy kodu).
Testy takie są wykonywane najczęściej przez testerów - osobny dział weryfikujący poprawność działania aplikacji. Developer oddaje aplikację do testów uruchamiając ją na środowisku stagingowym, po to aby testerzy mogli ją “przeklikać”.
Testy strukturalne (white-box testing)
Testy projektowane na podstawie znajomości kodu (stąd “biała skrzynka”), tak aby przetestować wszystkie ścieżki w kodzie. Z tego powodu piszą je zwykle programiści albo testerzy, którzy znają implementację.
Przykładem jest sytuacja, w której programiści modyfikują kod aplikacji, aby przetestować przypadki, które ciężko zreprodukować w środowisku uruchomionej aplikacji (na przykład modyfikacja czasu na urządzeniach takich jak telewizory).
Testy statyczne
Autorzy kodu, czytają kod źródłowy w poszukiwaniu błędów składni, ale też procesów biznesowych.
Takie testy realizowane są najczęściej podczas code review innego developera. Z mojego doświadczenia są to testy bardzo pomocne w zakończeniu zadania - na Twój kod patrzy cały zespół projektowy.
Moje doświadczenie pokazuje, że warto spotkać się jako zespół i porozmawiać o konkretnej zmianie, przed wdrożeniem.
Jeśli realizujecie swoje projekty na GitHubie (albo GitLabie) to świetnie jest spotkać się zespołem na omawianiu danego Pull Request-u. Wszyscy skupiają się tylko na tej jednej zmianie (która może oczywiście dotyczyć wielu plików).
Testy dynamiczne
Porównywanie danych wyjściowych z oczekiwanymi.
Na analizowanym kodzie (w testach statycznych) dorzucamy testowanie kodu uruchamiając z przykładowymi danymi w oczekiwaniu na dane wyjściowe, które to powinny być zgodne z flow implementacji logiki biznesowej (albo algorytmu).
Podsumowanie
Wystarczy zapamiętanie tych kilku typów testów, wśród których najważniejsze są 3 pierwsze, a komunikacja w zespołach projektowych może się poprawić.
Zachęcam wszystkich, którzy jeszcze nie pisali testów jednostkowych albo integracyjnych do spróbowania. Możecie się wzorować na moich projektach:
- https://github.com/piecioshka/test-jasmine-typescript
- https://github.com/piecioshka/test-jasmine-babel
- https://github.com/piecioshka/test-blanket-jasmine (Blanket.js jest porzucony; dziś pokrycie kodu mierzy Istanbul/nyc albo c8)
- https://github.com/piecioshka/test-mocha
- https://github.com/piecioshka/test-jest
Cya! 👋