Czym jest test jednostki?
Chyba nie ma programisty, który udostępni stworzony przez siebie
produkt nie testując go wcześniej. Z reguły każdy w jakiś sposób
testuje napisane przez siebie oprogramowanie. W większości wypadków są
to testy wykonywane ręcznie z wykorzystaniem graficznego interfejsu
systemu. W ten sposób programiści mogą przetestować działanie funkcji
systemu. Wyobraźmy sobie teraz, że nagle, po pewnej zmianie kodu jedna
z takich funkcji przestaje działać. Załóżmy, że wykonuje ona pewną
skomplikowaną operację biznesową. Programista testujący tylko od strony
interfejsu użytkownika może stwierdzić jedno – funkcja nie działa. Nie
wie natomiast, który z komponentów użytych do wykonania operacji uległ
awarii. W ten sposób można sprawdzić jedynie scalenie komponentów i
końcowy wynik ich współpracy. Nie można natomiast sprawdzić
poszczególnych komponentów w izolacji. Są to testy scalenia (ang.
integration tests).
Testy jednostek (ang. unit tests) badają
tworzone oprogramowanie na niższym poziomie. Najmniejszą jednostką
rozpatrywaną w takich testach jest klasa i jej poszczególne metody.
Testy te sprawdzają klasę w izolacji. Roy Osherove tak określa dobry
test jednostki [1]:
- Jest automatyczny i powtarzalny.
- Jest prosty w realizacji.
- Każdy może go wykonać.
- Można go wykonać jednym przyciśnięciem guzika.
- Wykonuje sie bardzo szybko.
Powyższy spis cech charakterystycznych można uzupełnić o jeszcze kilka:
- Jest niezależny od testów innych jednostek.
- Dostarcza dokładnej informacji, co i gdzie sie zepsuło.
Jest automatyczny i powtarzalnyTesty
jednostek z założenia maja służyć programiście pomocą. Programista nie
może być za każdym razem zmuszany do ręcznej weryfikacji wyników
testów. Po pierwsze jest to żmudna robota, a po drugie człowiek nie
jest nieomylny i jest prawdopodobne, że sklasyfikuje błędny wynik testu
jako poprawny. Testy powinny sie wykonywać automatycznie. Podobnie
powinno być z klasyfikacją tego czy test przechodzi, czy nie.
Programiście powinny być dostarczane tylko informacje o tym, które
testy przechodzą, a które nie. Ponadto testy powinny być powtarzalne.
Jeśli test przechodzi, to każde jego ponowne wykonanie ma dać taki sam
wynik (o ile nie zmodyfikowaliśmy kodu). Nie może być sytuacji, w
której test zwraca rożne wyniki przy takim samym wejściu. Taki test
byłyby bezużyteczny.
Jest prosty w realizacjiAby
efektywnie tworzyć testy jednostek, ich napisanie nie powinno sprawiać
trudności. Jest to jedna z większych różnic miedzy testami jednostek a
testami scalenia. Testy scalenia sprawdzają pewien zbiór
współpracujących klas. To pociąga za sobą konieczność odpowiedniego ich
połączenia przed wykonaniem testu. Napisanie testu staje sie przez to
bardziej skomplikowane i podatne na błędy. Natomiast testy jednostek
weryfikują klasę w izolacji, dzięki czemu sam test jest prosty do
napisania i nie wymaga zajmowania sie czasami skomplikowanymi
zależnościami miedzy klasami.
Każdy może go wykonaćTesty
jednostek są pomocą dla programisty, który je napisał, realizując daną
funkcję. Są także pomocą dla innych programistów w zespole. Każda
zmiana kodu programu niesie ryzyko wprowadzenia błędu. Nawet jeśli nie
modyfikujemy czyjegoś kodu, to jednak możemy coś zepsuć. Jeśli będziemy
mogli wykonywać wszystkie testy jednostek, nie tylko te, które sami
napisaliśmy, to będziemy mieli pewność, że nic nie zepsuliśmy.
Można go wykonać jednym przyciśnięciem guzikaTesty
muszą być łatwo wykonywalne, w przeciwnym wypadku nikt nie będzie
chciał z nich korzystać. Czasami może się zdarzyć, że aby wykonać jakiś
test, trzeba odpowiednio przygotować środowisko. Z reguły są to
czynności, których nie można wykonać automatycznie. Jest wysoce
prawdopodobne, że członkowie zespołu będą unikali wykonywania takiego
testu.
Wykonuje sie bardzo szybkoJeśli chcesz w pełni
korzystać z możliwości, które dają testy jednostek, to muszą się one
wykonywać w ułamku sekundy. Programowanie sterowane testami zakłada, ze
testy te będą wykonywane po każdej nawet najmniejszej zmianie. Jest to
szczególnie widoczne podczas refaktoryzacji.
Jest niezależny od innych testów jednostekTesty
jednostek nie mogą zależeć jeden od drugiego i nie powinny zależeć od
żadnych zewnętrznych zasobów. Cała ich konfiguracja ma być zawarta w
nich samych. Na przykład wyobraźmy sobie dwa testy, z których jeden
zapisuje rekord do bazy danych, a drugi próbuje go odczytać. Jeśli
pierwszy test nie zostanie wykonany, a w bazie nie będzie odpowiedniego
rekordu, to drugi test zakończy sie niepowodzeniem, mimo ze testowana
funkcja systemu jest poprawna. Inny przykład: test zależy od jakiegoś
zewnętrznego zasobu, powiedzmy pliku. Na maszynie, na której taki plik
istnieje, test będzie sie kończył sukcesem. Natomiast u innego
programisty, który nie będzie miał tego pliku test będzie sygnalizował
błąd.
Dostarcza dokładnej informacji, co i gdzie sie zepsułoW
przeciwieństwie do testów scalenia, test jednostki ma dokładnie
wskazywać miejsce awarii. Dzięki temu programista może szybko i
efektywnie zlokalizować błąd i go poprawić. Test jednostki powinien
sprawdzać tylko jedną funkcję systemu, co pozwoli na szybką
identyfikację potencjalnego miejsca, w którym wystąpił problem.
[1] Osherove R.: The Art of Unit Testing. Manning Publications Co, 2006. Draft.