Hlavní menu

Nástroje

WebKiv / TestovanieCezSpring

View (print) - Edit page | Recent changes - Page history

Updated 26 May 2010, 21:43 by Peter Cipov

WebKiv.TestovanieCezSpring History

Hide minor edits - Show changes to output

26 May 2010, 21:43 by Peter Cipov -
Changed line 11 from:
* webkiv-db.v2.02 (použite vždy najnoší).
to:
* webkiv-db.v2.02 (použite vždy najnovší).
26 May 2010, 20:14 by Peter Cipov - Ukážka testovania cez framework Spring
Changed lines 128-239 from:
@]
to:
@]

!! Jednotkové testy
Jednotkové testy slúžia na testovanie jednotiek, ktoré sú nezávislé na prostredí, teda aj na kontajnery ako Spring. Ten pri týchto testoch nepoužívame – ten si necháme do integračných testov. Vďaka tomu že je použitá architektúra „inverzia kontroly“ je veľmi jednoduché testovať jednotkovo, pretože vkladať závislosti je triviálna záležitosť (Vkladá sa cez setter). Podstatný znepríjemnením tejto práce je neustále vytváranie testovacích implementácií. Na pomoc však k nám prichádza mockito framework. Vďaka nemu je možné vytvoriť testovacie implementácie na pár riadkoch. Napríklad:

[@
//You can mock concrete classes, not only interfaces
LinkedList mockedList = mock(LinkedList.class);

//stubbing
when(mockedList.get(0)).thenReturn("first");
when(mockedList.get(1)).thenThrow(new RuntimeException());

//following prints "first"
System.out.println(mockedList.get(0));

//following throws runtime exception
System.out.println(mockedList.get(1));

//following prints "null" because get(999) was not stubbed
System.out.println(mockedList.get(999));
@]

!!!! UnitTest.java
[@
import cz.zcu.kiv.db.dao.TemaDao;
import cz.zcu.kiv.db.model.studium.StavPrace;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.springrepository.pokus.impl.ImplC;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

public class UnitTest {

@Test
public void test1() {

final String i1val = "i1val";
final String i2val = "i2val";

final String name = "name";
final String meno = "meno";
final List<StavPrace> stavy = Arrays.asList(new StavPrace[] {
new StavPrace(),
new StavPrace(),
new StavPrace()
});
int i =0;
for(StavPrace s : stavy) {
s.setId(i);
s.setNazevCz(meno+i);
s.setNazevEn(name+i);
}


ImplC i3 = new ImplC();

Intr1 i1 = mock(Intr1.class);
when(i1.do1()).thenReturn(i1val);
i3.setIntr1(i1);

Intr2 i2 = mock(Intr2.class);
when(i2.do2()).thenReturn(i2val);
i3.setIntr2(i2);

TemaDao dao = mock(TemaDao.class);
when(dao.getStavyPrace()).thenReturn(stavy);
i3.setTemaDao(dao);

StringBuilder sb= new StringBuilder(i1.do1() + i2.do2() + Intr3.DELIMITER);
for(StavPrace sp : stavy) {
sb.append(sp.getId() + sp.getNazevCz()+ Intr3.DELIMITER);
}

assertEquals(sb.toString(), i3.do3());

}

}
@]
Ako vidieť na príklade, test nie je závislý na žiadnych vonkajších triedach, všetky implementácie, okrem tej testovanej, sú nahradené. Vďaka frameworku mockito je vytvorenie náhrad jednoduché a rýchle.

!! Integračné testy
Integračné testy slúžia na testovanie interakcií medzi jednotkami. Na to už je nutné použiť spring framework,ktorý zabezpečí vytvorenie jednotiek a ich previazanie. Do testu ho zakomponujeme takto:

[@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/org/springrepository/pokus/config.xml", "/redsys-servlet.xml"})
public class IntegrationTest {

@Autowired
private Intr3 intr3;

@Test
public void test1() {
intr3.do3();
}
}
@]


Prvá anotácia @RunWith zabezpečí to že pri spúšťaní tejto testovacej triedy sa vytvorí Spring kontajner. @ ContextConfiguration určí miesto, kde sa nachádzajú konfiguračné xml súbory.
@Autowired slúži na nahratie potrebných služieb. Vlastnosť každého testu v takejto triede je že je transakčná. Po každom vykonaní testu sa vykoná rollback, teda ani databáza nebude zahltená zbytočnými dátami.
26 May 2010, 20:11 by Peter Cipov - Ukážka testovania cez framework Spring
Added lines 1-128:
Spring ako framework dodáva podporu pre testovanie pomocou JUnit alebo TestNG. V našich príkladoch sa predpokladá výber JUnit a preto už ďalej budem pod pojmami testovaci framework (tf) myslieť práve JUnit.
Pri testovaní rozoznávame dva druhy testov v tf:
# jednotkové
# integračné
Pre oba existuje v Spring podpora, preto uvediem príklady pre oba druhy testov.

!! Ako si vytvoriť testovacie prostredie

Ako základ budeme využívať triedy z webkiv-db.v2.02.jar. Budú tvoriť základné dao triedy. Ďalej je nutný redsys-servlet.xml ako popisovač základného kontextu. To by stačilo, keby sa jednalo o desktopovu aplikaciu, kedže je sa jedna o webovu zaležitosť su nutne tieto knižnice v classpath projektu:

* webkiv-db.v2.02 (použite vždy najnoší).
* spring 2.5 + cglib2.2 + commons-logging1.1
* log4j-1.2.9
* spring webmvc 2.5
* cz.zcu.kiv.opencms.common
* mysql-connector
* servlet.api (najdete v tomcat lib)

Ako testovacie knižnice je nutné si nastaviť:
* JUnit 4.5 (junit.org)
* org.springdramework.test 3.0 – kompatibilne so springom 2.5 (http://www.springsource.com/repository/app/ do search zadas nazov )
* mocktito-all1.8.4 mockito.org/

Ako tam dostať však ten redsys-servlet.xml a webkiv.properties ? Ja osobne si vytvorím extra prázdny projekt kde tieto súbory dám do najvyžšieho balíku. Drobnou chybičkou na kráse je nutnosť vytvorenia WEB-INF priečinka v tomto projekte, inak to zahlási chybu. Tento projekt pridám ako závyslosť do nášho hlavného projektu a máme hotovo.

!! Ukážkový príklad
Vytvoríme si projekt s názvom Pokus. V tomto projektu si vytvoríme hlavný balík org.springrepository.pokus. V ňom vytvoríme tieto súbory:


!!!! Intr1.java
[@
public interface Intr1 {

public String do1();

}
@]

!!!! Intr2.java
[@
public interface Intr2 {

public String do2();

}
@]

!!!! Intr3.java
[@
public interface Intr3 {

public static final String DELIMITER = " <br />";

public String do3();
}
@]

Následne si vytvoríme podbalík impl a v nom tieto súbory:

!!!! ImplA.java
[@
public class ImplA implements Intr1{

public String do1() {
return "Ahoj";
}

}
@]

!!!! ImplB.java
[@
public class ImplB implements Intr2{

public String do2() {
return "Svete";
}

}
@]

!!!! ImplC.java
[@
import cz.zcu.kiv.db.dao.TemaDao;
import cz.zcu.kiv.db.model.studium.StavPrace;
import java.util.List;
import org.springrepository.pokus.Intr1;
import org.springrepository.pokus.Intr2;
import org.springrepository.pokus.Intr3;

public class ImplC implements Intr3{

private Intr1 intr1;
private Intr2 intr2;
private TemaDao temaDao;


public void setIntr1(Intr1 intr1) {
this.intr1 = intr1;
}

public void setIntr2(Intr2 intr2) {
this.intr2 = intr2;
}

public void setTemaDao(TemaDao temaDao) {
this.temaDao = temaDao;
}

public String do3() {
StringBuilder sb= new StringBuilder(intr1.do1() + intr2.do2() + DELIMITER);
if(temaDao !=null) {
List<StavPrace> stavyPrace = temaDao.getStavyPrace();

for(StavPrace sp : stavyPrace) {
sb.append(sp.getId() + sp.getNazevCz()+ DELIMITER);
}

} else {
sb.append("temaDao je null");
}

return sb.toString();

}

}
@]