4it101»J Unit 5

J Unit 5

Testování polí a seznamů (Collection, Map)

Testování seznamů

Máte k dispozici nějaký seznam (Collection, List, Set, ArrayList, HashSet ...) a potřebujete otestovat existenci prvků v seznamu. Následující ukázky budou vycházet z příkladu zapasy3?, ve kterém jsou dvě metody, které vrací seznamy:

     public Collection<Hrac> seznamHracu()
     public Collection<Integer> cislaDresu()

V obou případech je návratový typ Collection, tj. neznáme zvolenou implementaci, při testování můžeme používat pouze metody předepsané v tomto rozhraní. Při testu se obvykle:

  • zkontroluje počet prvků - metoda size(), popř. metoda isEmpty()
  • pomocí metody contains() se zkontroluje existence jednotlivých prvků

Následuje test pro odebrání hráče - do týmu vložím dva hráče, jednoho z nich odeberu a poté zkontroluji, že metoda seznamHracu() vrací seznam s jedním prvkem (řádek 11 následujícího kódu) a tímto prvkem je konkrétní hráč (řádek 12).

  1.     @Test
  2.     public void testOdeberHrace()
  3.     {
  4.         Tym tym1 = new Tym("Ekonom Praha");
  5.         Hrac hrac1 = new Hrac("Petr", 1);
  6.         Hrac hrac2 = new Hrac("Pavel", 2);
  7.         tym1.pridejHrace(hrac1);
  8.         tym1.pridejHrace(hrac2);
  9.  
  10.         tym1.odeberHrace(hrac1);
  11.         assertEquals(1, tym1.seznamHracu().size());
  12.         assertEquals(true, tym1.seznamHracu().contains(hrac2));
  13.     }

Jiným příkladem je test metody seznamCiselDresu(), která vrací seznam čísel dresů, která jsou již přiřazena některým hráčům. Princip testu je stejný, navíc kontroluji, že na začátku je seznam čísel dresů prázdný (řádek 8). V metodě contains uvádím číslo typu int - není potřeba používat typ Integer, neboť Java provádí automatické konverze (autoboxing).

  1.     @Test
  2.     public void testSeznamCiselDresu1() {
  3.         Tym tym1 = new Tym("Ekonom Praha");
  4.         Hrac hrac1 = new Hrac("Petr", 1);
  5.         Hrac hrac2 = new Hrac("Pavel", 5);
  6.  
  7.         // v týmu bez hráčů by seznam čísel dresů měl být prázdný
  8.         assertEquals(true, tym1.cislaDresu().isEmpty());
  9.  
  10.         tym1.pridejHrace(hrac1);
  11.         tym1.pridejHrace(hrac2);
  12.  
  13.         // test lze udělat přes kontrolu velikosti (size)
  14.         // a kontrolu prvků pomocí contains
  15.         assertEquals(2, tym1.cislaDresu().size());
  16.         assertEquals(true, tym1.cislaDresu().contains(1));
  17.         assertEquals(true, tym1.cislaDresu().contains(5));
  18.     }

Testování seznamů 2 - očekávaný seznam

Při testování seznamů lze využít metodu containsAll(), která vrací true, pokud kolekce obsahuje všechny prvky uvedené v parametru (seznamu). Při kontrole se musí buď

      kontrolovat velikost vysledku (počet prvků pomocí metody size())
      a výsledek musí obsahovat všechny prvky očekávaného seznamu (vysledek.containsAll(ocekavanySeznam))

nebo

      se musí provést kontrola "oboustranně"  (vysledek.containsAll(ocekavanySeznam) i ocekavanySeznam.containsAll(výsledek))
  1. @Test
  2. public void testSeznamCiselDresu2() {
  3.     Tym tym1 = new Tym("Ekonom Praha");
  4.     Hrac hrac1 = new Hrac("Petr", 1);
  5.     Hrac hrac2 = new Hrac("Pavel", 5);
  6.  
  7.     // v tymu bez hracu by seznacm cisel dresu měl být prazdný
  8.     assertEquals(true, tym1.cislaDresu().isEmpty());
  9.  
  10.     tym1.pridejHrace(hrac1);
  11.     tym1.pridejHrace(hrac2);
  12.  
  13.     // následuje kontrola pomocí očekávaného seznamu
  14.     List<Integer> ocekavanySeznam = new ArrayList<>();
  15.     ocekavanySeznam.add(5);
  16.     ocekavanySeznam.add(1);
  17.     assertEquals(true, tym1.cislaDresu().containsAll(ocekavanySeznam));
  18.     assertEquals(true, ocekavanySeznam.containsAll(tym1.cislaDresu()));
  19. }

Testování polí

Pro porovnávání polí potřebujeme dva prvky:

  • očekávané pole
  • metodu, která umí porovnat pole - metoda assertArrayEquals z knihovny JUnit.

Testování polí si ukážeme na zadání s polem mincí?.

Očekávané pole je potřeba vytvořit v testovací třídě. Doporučuji jej vytvářet v pomocných privátních metodách - testovací metody budou poté kratší a přehlednější. Privátní metoda by mohla vypadat následovně, pro testování budete potřebovat více metod(pro různé testy):

    private Mince [] ocekavanePole1() {
        Mince [] poleMinci = new Mince[20];
        poleMinci[2] = new Mince("stříbrná", "coin.png");
        poleMinci[3] = new Mince("stříbrná", "coin.png");
        poleMinci[4] = new Mince("zlatá", "coin_gold.png");
        poleMinci[9] = new Mince("stříbrná", "coin.png");
        poleMinci[12] = new Mince("stříbrná", "coin.png");
        return poleMinci;
    }

Pro porovnání polí využijte metodu assertArrayEquals z knihovny JUnit. Pro její použití musí mít prvky pole naprogramovanou metodu equals(). Tj. je potřeba do třídy Mince doplnit metody equals() a hashCode() (metoda hashCode není nutná, ale doporučená):

    @Override
    public boolean equals(Object o){
        if (!(o instanceof Mince)){
            return false;
        }
        Mince druha = (Mince)o;
        return nazev.equals(druha.nazev());
    }

    @Override
    public int hashCode(){
        return nazev.hashCode();
    }

Nyní bude test s porovnáním polí vypadat následovně (rozšiřuji předchozí test):

    @Test
    public void testTahHrace1() {
        Hra1 hra = new Hra1();
        Tah tah = new Tah(2, 0);
        assertEquals(false, hra.tahHrace(tah));
        assertArrayEquals(ocekavanePole1(), hra.getPoleMinci());
    }

Tento test úspěšně projde za předpokladu, že počáteční rozložení mincí ve třídě Hra odpovídá poli, jaké vrací metoda ocekavanePole1().

Pro porovnávání polí (pro většinu testů) je potřeba znát počáteční rozestavení mincí - to může být problém v situaci, kdy se na začátku vygeneruje náhodné rozmístění mincí (varianta 2 zadání). Testování náhodně rozmístěných mincí v poli je ukázáno v části věnované testování náhody.

Testování seznamů 3

  • Hamcrest
    @Test
    public void testSeznamCiselDresu3()
    {
        Tym tym1 = new Tym("Ekonom Praha");
        Hrac hrac1 = new Hrac("Petr", 1);
        Hrac hrac2 = new Hrac("Pavel", 5);

        // v tymu bez hracu by seznacm cisel dresu měl být prazdný
        assertThat(tym1.cislaDresu().isEmpty(), is(true));

        tym1.pridejHrace(hrac1);
        tym1.pridejHrace(hrac2);

        // kontrola počtu prvků
        assertThat(tym1.cislaDresu().size(), is(2));
        // následuje kontrola obsahu pomocí Matchers
        assertThat(tym1.cislaDresu(), hasItems(1,5));
    }