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).
@Test
public void testOdeberHrace()
{
Tym tym1 = new Tym("Ekonom Praha");
Hrac hrac1 = new Hrac("Petr", 1);
Hrac hrac2 = new Hrac("Pavel", 2);
tym1.pridejHrace(hrac1);
tym1.pridejHrace(hrac2);
tym1.odeberHrace(hrac1);
assertEquals(1, tym1.seznamHracu().size());
assertEquals(true, tym1.seznamHracu().contains(hrac2));
}
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).
@Test
public void testSeznamCiselDresu1() {
Tym tym1 = new Tym("Ekonom Praha");
Hrac hrac1 = new Hrac("Petr", 1);
Hrac hrac2 = new Hrac("Pavel", 5);
// v týmu bez hráčů by seznam čísel dresů měl být prázdný
assertEquals(true, tym1.cislaDresu().isEmpty());
tym1.pridejHrace(hrac1);
tym1.pridejHrace(hrac2);
// test lze udělat přes kontrolu velikosti (size)
// a kontrolu prvků pomocí contains
assertEquals(2, tym1.cislaDresu().size());
assertEquals(true, tym1.cislaDresu().contains(1));
assertEquals(true, tym1.cislaDresu().contains(5));
}
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))
@Test
public void testSeznamCiselDresu2() {
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ý
assertEquals(true, tym1.cislaDresu().isEmpty());
tym1.pridejHrace(hrac1);
tym1.pridejHrace(hrac2);
// následuje kontrola pomocí očekávaného seznamu
List<Integer> ocekavanySeznam = new ArrayList<>();
ocekavanySeznam.add(5);
ocekavanySeznam.add(1);
assertEquals(true, tym1.cislaDresu().containsAll(ocekavanySeznam));
assertEquals(true, ocekavanySeznam.containsAll(tym1.cislaDresu()));
}
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
@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));
}