Spis treści
Poniżej przedstawionych zostało kilka przykładów testów jednostkowych różnych metod.
Wartość bezwzględna¶
Spójrzmy na prosty przykład testów metody, której zadaniem jest zwrócenie wartości bezwględnej przesłanej liczby.
Dla liczb parzystych jest to ta sama liczba. Przykład: wartość bezwzględna liczby 10 to 10.
Dla liczb ujemnych jest to liczba bez minusa. Przykład: wartość bezwzględna liczby -5 to 5.
Zanim jednak przejdziemy do kodu źródłowego, zastanówmy się jak przetestowalibyśmy taką metodę? Jakie przypadki testowe wzięlibyśmy pod uwagę?
public class TestowanieWartoscBezwzgledna { public static void main(String[] args) { wartoscBezwgledna_liczbaDodatnia_zwrociDodatniaWartosc(); // (1) wartoscBezwgledna_liczbaUjemna_zwrociDodatniaWartosc(); // (2) } public static int wartoscBezwgledna(int x) { // (3) return x < 0 ? -x : x; } public static void wartoscBezwgledna_liczbaDodatnia_zwrociDodatniaWartosc() { // (4) int rezultat = wartoscBezwgledna(20); // (5) if (rezultat != 20) { // (6) System.out.println( // (7) "Dla wartosci 20 otrzymano nieprawidlowa wartosc: " + rezultat ); } } public static void wartoscBezwgledna_liczbaUjemna_zwrociDodatniaWartosc() { // (8) int rezultat = wartoscBezwgledna(-1); // (9) if (rezultat != 1) { // (10) System.out.println( // (11) "Dla wartosci -1 otrzymano nieprawidlowa wartosc: " + rezultat ); } } }
Przejdźmy krok po kroku przez powyższy kod:
- Metoda, którą chcemy przetestować, to wartoscBezwzgledna (3). Jest to prosta metoda wykonując jedno zadanie – dla podanej jako argument liczby zwraca wartość bezwzględną tej liczby.
- Metoda wartoscBezwzgledna testowana jest przez dwie metody (4) (8).
- Dane testowe pierwszej metody to liczba dodatnia (5), a drugiej metody – liczba ujemna (9).
- Obie metody testowe sprawdzają, czy wynik jest nieprawidłowy (6) (10) – jeśli tak, to wypisują informację na ekran (7) (11).
- Metody testowe wywołujemy w metodzie main (1) (2).
Metoda sprawdzająca, czy tablica zawiera element¶
Chcielibyśmy napisać metodę, która będzie przyjmowała jako argument tablicę liczb i odpowiadała na pytanie, czy w tej tablicy znajduje się dana liczba.
Jakie przypadki testowe powinniśmy przygotować?
Powinniśmy na pewno sprawdzić następujące przypadki:
- Co się stanie, jeżeli tablica jest pusta? – zawsze warto sprawdzić zachowanie na "pustych" danych.
- Co się stanie, jeżeli niepusta tablica nie zawiera szukanego elementu? – podczas wyszukiwania elementów warto sprawdzić co dzieje się, gdy element nie istnieje.
- Co się stanie, jeżeli niepusta tablica zawiera szukany element? – "normalny" przypadek.
- Co się stanie, jeżeli niepusta tablica zawiera szukany element wyłącznie na samym początku tablicy? – w przypadku operacji na tablicach warto brać pod uwagę przypadki testowe sprawdzające zachowanie biorące pod uwagę pierwszy element tablicy.
- Co się stanie, jeżeli niepusta tablica zawiera szukany element wyłącznie na samym końcu tablicy? – jak wyżej, ale tym razem bierzemy pod uwagę element końcowy.
Poniższy kod źródłowy przedstawia, jak moglibyśmy napisać powyższy program wraz z testami:
public class TestowanieCzyElementWTablicy { public static void main(String[] args) { czyZawieraElement_pustaTablica_zwrociFalse(); czyZawieraElement_brakSzukanegoElementu_zwrociFalse(); czyZawieraElement_zawieraSukanyElement_zwrociTrue(); czyZawieraElement_zawieraSukanyElementNaPoczatku_zwrociTrue(); czyZawieraElement_zawieraSukanyElementNaKoncu_zwrociTrue(); } public static boolean czyZawieraElement(int[] tablica, int liczba) { for (int i = 0; i < tablica.length; i++) { if (tablica[i] == liczba) { return true; } } return false; } public static void czyZawieraElement_pustaTablica_zwrociFalse() { // given int[] pustaTablica = {}; int liczba = 5; // when boolean czyZawiera = czyZawieraElement(pustaTablica, liczba); // then if (czyZawiera) { System.out.println( "Blad! Pusta tablica nie powinna nic zawierac." ); } } public static void czyZawieraElement_brakSzukanegoElementu_zwrociFalse() { // given int[] tablica = {-20, 100, 500}; int liczba = 128; // when boolean czyZawiera = czyZawieraElement(tablica, liczba); // then if (czyZawiera) { System.out.println( "Blad! Element 128 nie powinien byc znaleziony." ); } } public static void czyZawieraElement_zawieraSukanyElement_zwrociTrue() { // given int[] tablica = {2, 4, 8, 16, 32, 64, 128, 256}; int liczba = 128; // when boolean czyZawiera = czyZawieraElement(tablica, liczba); // then if (!czyZawiera) { System.out.println( "Blad! Element 128 powinien byc znaleziony." ); } } public static void czyZawieraElement_zawieraSukanyElementNaPoczatku_zwrociTrue() { // given int[] tablica = {100, 200, 300}; int liczba = 100; // when boolean czyZawiera = czyZawieraElement(tablica, liczba); // then if (!czyZawiera) { System.out.println( "Blad! Element 100 powinien byc znaleziony." ); } } public static void czyZawieraElement_zawieraSukanyElementNaKoncu_zwrociTrue() { // given int[] tablica = {100, 200, 300}; int liczba = 300; // when boolean czyZawiera = czyZawieraElement(tablica, liczba); // then if (!czyZawiera) { System.out.println( "Blad! Element 300 powinien byc znaleziony." ); } } }
Testy zapisaliśmy zgodnie z notacją given .. when .. then – najpierw przygotowujemy dane, następnie wywołujemy testowaną metodą i zapisujemy jej wynik, a na końcu sprawdzamy wynik.
Powyższe testy są proste – mogłyby również być zapisane w bardziej zwięzły sposób, na przykład:
public static void czyZawieraElement_zawieraSukanyElementNaKoncu_zwrociTrue() { if (!czyZawieraElement(new int[] {100, 200, 300}, 300)) { System.out.println( "Blad! Element 300 powinien byc znaleziony." ); } }
Powyższy przykład pomija sekcje "given", "when" oraz "then" i znacząco skraca test – jest on na tyle prosty, że taka postać mogłaby być preferowana, ale w ramach ćwiczenia i przykładu użyta została konwencja given .. when .. then.
Na górze strony chyba "Dla liczb parzystych..." , zdaje się, że miałeś na myśli dodatnich 🙂
Tak, masz rację 🙂