JUnit został stworzony przez dwójkę programistów - Ericha Gamma i Kenta Becka. Jest to narzędzie wspomagające pisanie i przeprowadzanie testów dla programów pisanych w Javie. Udostępnia on między innymi prosty interfejs graficzny, dzięki któremu możemy uruchamiać przygotowane testy. JUnit pozwala nam:
JUnit został stworzony z myślą o programistach piszących programy zgodnie z metodologią Extreme Programming. Doświadczenie wielu programistów udowadnia, że w procesie powstawania oprogramowania bardzo dużą rolę odgrywają automatyczne testy. Przygotowanie testów dla gotowych aplikacji jest często trudne, jeśli nie nie możliwe. Jedną z praktyk programistycznych ułatwiających pisanie złożonych aplikacji jest właśnie Test Driven Development. Jej głównym założeniem jest zmiana podejścia do testów. W klasycznym podejściu najpierw tworzony jest kod, a następnie testy mające sprawdzić jego poprawne działanie. W TDD pisanie testów jest postawione na pierwszym miejscu.
W największym skrócie powstawanie kodu powinno wyglądać następująco:
Dzięki JUnit pisanie i uruchamianie testów jest łatwe i wydajne. Organizacja testów w zestawy pozwala nam oddzielić często uruchamiane małe zestawy testów od przygotowanych wcześniej zestawów uruchamianych raz dziennie i testujących dużą część tworzonej aplikacji. Wygodny i prosty interfejs pozwala łatwo uruchamiać wybrane zestawy testów, nawet te napisane pół roku wcześniej.
Ten punkt nie odpowiada na pytanie "Kiedy pisać testy?". Częściowa odpowiedź na tak postawione pytanie znajduje się w poprzedniej części. Na potrzeby prezentacji wyłamujemy się jednak z tego schematu. Przypuśćmy, że stworzyliśmy prostą klasę Multiplier:
public class Multiplier { private int temp;public int multiply(int a,int b) {
public int pow(int a,int n) {
return a*b;
}
while (n>0) {
temp *= a;
n--;
}
return temp;
}
}
Klasa ta udostępnia dosyć wąską funkcjonalność, pozwala pomnożyć przez siebie parę liczb całkowitych, oraz podnieść liczbę do określonej potęgi. Co zrobić, żeby sprawdzić, czy klasa spełnia swoją funkcjonalność? Po pierwsze tworzymy klasę dziedziczącą po klasie TestCase z pakietu JUnit:
import junit.framework.*; public class MultiplierTest extends TestCase{ }
Klasa ta zawierała będzie:
Kolejnym krokiem jest zainicjowanie obiektów, które będziemy testowali. Oczywiści możemy zrobić to dopiero dopiero w metodach testujących, ale poniższy przykład zilustruje nam mechanizm pozwalający inicjalizować obiekty wykorzystywane w wielu testach:
private Multiplier m;
protected void setUp(){ m = new Multiplier(); }
Metoda setUp()
uruchamiana jest przed każdym uruchomieniem testów
z naszej klasy. Dzięki czemu możemy w niej umieścić kod, który inczej musielibyśmy
wielokrotnie przepisywać w każdej z metod testujących. Następny krok, to właśnie
napisanie metod testujących:
public void testMultiply() { assertTrue(m.multiply(2,3) == 6 ); } public void testPow(){ assertEquals("2^4 = 16", 16, m.pow(2,4)); }
Do sprawdzania warunków używamy udostępnianych przez JUnit metod assertTrue,
assertEquals
itp. Jako parametr możemy przekazać warunek logiczny, jak
również obiekt klasy String. Jeśli test się nie powiedzie powyższy napis stanowił
będzie jedną z informacji identyfikujących test, który nie przeszedł. Kolejnym
krokiem jest utworzenie instancji tworzonej klasy uruchamiającej wybrany test:
new MultiplierTest("testMultiply");
Przekazywany parametr, jest jednocześnie nazwą identyfikującą test, oraz nazwą
metody którą powyższy test wywoła. Przy uruchamianiu testów standartowo uruchamiana
jest metoda runTest()
, która domyślnie wyszukuje metodę o podanej
nazwie i ją wywyołuje. Często stosowaną praktyką jest nadpisywanie tej metody.
Taki mechanizm pozwala tworzyć testy uruchamiające np. kilka wybranych metod.
Najłatwiejszą metodą nadpisywania tej metody jest stworzenie anonimowej klasy
implementującej metodę runTest()
w wybrany przez nas sposób.
new MultiplierTest("test potęgowania") { protected void runTest(){ testPow(); } }
Jeśli chcemy uruchomić kilka testów jednocześnie, możemy utworzyć zestawu testów. Najprostszą metodą jest wywołanie konstruktora zestawu testów z nazwą naszej przekazaną jako parametr. Konstruktor ten automatycznie wydobędzie z naszej klasy wszyskie testy i dołączy je do tworzonego zestawu testów:
TestSuite suite= new TestSuite(MultiplierTest.class);
Ostatnim krokiem, który chcemy wykonać jest uruchomienie zestawu testów. JUnit
udostępnia mechanizm, który automatycznie uruchamia wybrane testy i przedstawia
ich wyniki w czytelnej postaci. Po pierwsze musimy w naszej klasie zdefiniować
metodę public static Test suite()
. Poniższy przykład zilustruje
również drugą metodę tworzenia zestawu testów:
public static Test suite(){ TestSuite suite = new TestSuite();
suite.addTest( new MultiplierTest() { protected void runTest(){ testPow();} } ); Test test1 = new MultiplierTest(){ protected void runTest() { testMultiply(); } };
suite.addTest(test1);
return suite; }
Tak stworzony zestaw testów można już łatwo uruchomić korzystając z tekstowego lub jednego z graficznych narzędzi udostępnianych przez JUnit. Uruchamiamy je wpisując z linii poleceń: java junit.awtui.TestRunner lub java junit.swingui.TestRunner.
W polu Test class name wpisujemy nazwę klasy, zawierającej test, który chcemy uruchomić. Następnie klikamy przycisk Run. W polu results pojawi się podsumowanie wyników przeprowadzonego testu. W tym przypadku okazało się, że jedna z testowanych metod nie działa poprawnie. Po naniesieniu oczywistej poprawki:
public int pow(int a,int n) { temp = 1; while (n>0) { temp *= a; n--; } return temp; }
Ponownie kompilujemy klasę multiplier, i uruchamiamy TestRunner'a:
Jeśli wszystkie testy zakończyły się powodzeniem TestRunner zasygnalizuje to zielonym kolorem paska stanu testów.
Dodatkowe informacje można znaleźć na poniższych stronach internetowych: