ZASADY EFEKTYWNEGO PISANIA TESTÓW Janusz Marchewa
Plan prelekcji Przyczyny występowania problemów Problem 1: zależności pomiędzy testowanymi klasami Problem 2: niskie pokrycie kodu przez testy Inne problemy
Przyczyny występowania problemów
Przyczyny występowania problemów “Kod aplikacji musi być dobrze napisany, testy mają tylko go przetestować” “Nie mam czasu, żeby przyłożyć się do pisania testów – terminy gonią” “O co chodzi? Przecież umiem pisać testy” “Skąd miałem wiedzieć, że takie rozwiązanie może powodować problemy?”
Problem 1
Zależności pomiędzy testowanymi klasami
Moki (mock objects) Specjalnie przygotowane na potrzeby testów implementacje interfejsów (lub w przypadku jego braku – dziedziczące z klasy konkretnej) Ułatwiają pisanie testów jednostkowych Nie trzeba martwić się o zależności testowanej klasy Zawsze zachowają się zgodnie z naszymi oczekiwaniami
Moki statyczne
Moki dynamiczne Powstają w pamięci i nie obciążają projektu dziesiątkami dodatkowych klas Umożliwiają proste definiowanie właściwie dowolnych zachowań Oferują szerokie możliwości weryfikacji rzeczywistych interakcji z testowaną klasą Najpopularniejsze biblioteki:
Moki dynamiczne (sposób wykorzystania) 1. Tworzymy moka i definiujemy nasze oczekiwania. 2. Podstawiamy go do testowanej klasy. 3. Wywołujemy testowaną metodę. 4. Weryfikujemy interakcje testowanej klasy z mokiem.
Więcej informacji Andrew Hunt & David Thomas, Pragmatic Testing in Java with JUnit, The Pragmatic Programmers 2003 http://tap.testautomationpatterns.com:8080/ Hard%20to%20Test%20Code.html http://www.mockobjects.com http://jmock.codehaus.org http://www.easymock.org
Problem 2
Niskie pokrycie kodu przez testy
Niskie pokrycie kodu przez testy Odpowiednio długi login i adres email mogą spowodować przepełnienie typu long Kod został poprawiony i testy nadal działały Ponowne uruchomienie aplikacji ujawniło inny błąd, wprowadzony przypadkowo w trakcie poprawiania kodu Wniosek: test był niewystarczający, ponieważ nie sprawdzał, czy wykryty błąd został zlikwidowany
Pokrycie kodu przez testy (code coverage) Określa, jaka część kodu aplikacji jest wykonywana w wyniku uruchomienia testów Możemy odpowiednio zareagować i dopisać testy tam, gdzie ich brakuje Najczęściej wykorzystywane rodzaje: Statement coverage (czy wszystkie instrukcje zostały wykonane) Branch coverage (czy wszystkie możliwe ścieżki zostały prześledzone)
Narzędzia do badania pokrycia kodu przez testy Clover (http://www.cenqua.com/clover) Cobertura (http://cobertura.sourceforge.net) JBlanket (http://csdl.ics.hawaii.edu/Tools/JBlanket) NoUnit (http://nounit.sourceforge.net) Coverlipse (http://coverlipse.sourceforge.net) ...
Programowanie sterowane testami (TDD) Najpierw piszemy test, a potem kod, który ten test spełnia Zalety: wysokie pokrycie kodu przez testy mniejszy stopień skomplikowania modułów łatwe odnajdywanie błędów pełna automatyzacja testów Żaden kod nie może powstać, dopóki nie istnieje niedziałający test!
Red-green-refactor
Efekty zastosowania TDD W każdym momencie mamy pewność, że zmierzamy we właściwym kierunku Gdy pojawia się błąd, od razu wiemy, gdzie go szukać Uzyskujemy kod bardzo dobrze pokryty przez testy, ponieważ test jest zawsze punktem wyjścia do napisania kodu System staje się prostszy, ponieważ nie ma w nim niepotrzebnego kodu
Zasady, o których warto pamiętać Najpierw test, potem kod, ale w podejściu iteracyjnym (pojedynczy przypadek testowy, kod, przypadek testowy, kod, ...) Dobre nazewnictwo klas, zmiennych, metod Prosty i czytelny kod Częsty refaktoring Regularne uruchamianie potrzebnych testów
Więcej informacji Kent Beck, Test Driven Development: By Example, Addison Wesley 2002 David Astels, Test Driven Development: A Practical Guide, Prentice Hall PTR 2003 http://tap.testautomationpatterns.com:8080/ Missing%20Test.html http://www.testdriven.com http://www.agiledata.org/essays/tdd.html
Inne problemy
Inne problemy Kod trudny do przetestowania Zależności pomiędzy metodami testującymi Zbyt złożone metody testujące ... http://tap.testautomationpatterns.com:8080/Test%20Smells.html
Więcej informacji Rod Johnson & Juergen Hoeller, Expert One- on-One J2EE Development without EJB, Wiley 2004 Michael Feathers, Working Effectively with Legacy Code, Prentice Hall PTR 2004 http://tap.testautomationpatterns.com:8080 http://www.cwi.nl/~leon/papers/xp2001/ http://www.agilealliance.com/articles/smithshaunmeszarosger
Dziękujemy za uwagę!