SlovnikTerminologie: TestyJUnit

from Wiki KIVu

Testování pomocí JUnit?


1.6.2013 - Existující JUnit testy SPOTu byly z důvodu jejich neaktuálnosti odstaveny.


Take vyjmuto z me BP. (TP)

Volba řešení

Jako základní kámen pro testování aplikace jsem zvolil Spring TestContext? framework. Přestože jde o poměrně mladou součást Springu, přidána ve verzi 2.5, nebál jsem se ji použít.

JUnit?

JUnit? je framework sloužící k testování aplikací napsaných v jazyce Java. Vyvíjí ho mimo jiné Kent Beck, Erich Gamma a David Saff. Jde o open source projekt vydaný pod Common Public Licence.

Při testování se používají dva druhy tříd. Prvním jsou takzvané Suite classes, které primárně určují, které třídy s testy se mají spustit. Na třídy s testy mohou odkazovat buď přímo a nebo přes další Suite.class. A druhým druhem jsou třídy s vlastními testy.

Vlastní testování uvnitř testované metody se provádí na základě porovnávání získaných hodnot s hodnotami očekávanými. Toto porovnání nám umožnují metody frameworku z balíku org.junit.Assert. Představím některé z nich:

Za představení jistě stojí pár základních anotací k metodám i třídám. Tyto anotace se používají namísto konvence z JUnit? 3.8.x.

Při spouštění testů přes Maven příkazem mvn test nám Maven vygeneruje v adresáři target adresář surefire-report, který obsahuje soubory s výsledky jednotlivých testovaných tříd. V nich nalezneme buď statistiku testů dané třídy a nebo chybovou hlášku v případě, že došlo k nějaké chybě.

Realizace

Spouštěcí třídou pro testy je prostá třída SpotSuiteTests.

@RunWith(Suite.class)
@SuiteClasses(value={DaoSuiteTests.class, ControllerSuiteTests.class})
public class SpotSuiteTests {	
}

Jde o základní suite třídu, která odkazuje na další suite třídy v jednotlivých podbalících aplikace. Třídy, které tato třída dále spouští, jsou uvedeny v anotaci @SuiteClasses. Jde o následující třídy DaoSuiteTests.class a ControllerSuiteTests.class. Takováto třída nemusí obsahovat žádnou metodu. Vše důležité je zaneseno v anotacích třídy.

@RunWith(Suite.class)
@SuiteClasses(value={WordDaoImplTest.class})
public class DaoSuiteTests {    
}

Toto je suite třída, ve které je nadefinována třída ke spuštění podle vzoru z předchozích řádek.

Základem tesování DAO tříd aplikace je načtení bean pomocí Inversion of Control. Toto načtení konfigurace jsem se rozhodl realizovat přes abstraktní třídu AbstractDaoTests, od které by měli dědit všechny třídy s testy v tomto balíku.

 @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:dao-context.xml"})
public abstract class AbstractDaoTests 
                extends AbstractTransactionalJUnit4SpringContextTests {

První anotace říká, že tuto třídu bude spouštět třída SpringJUnit4ClassRunner, která zajišťuje, že se třída nespustí jako běžná třída s testy, ale průběh testování bude řídit Spring framework. Další anotace definuje umístění souboru s konfigurací. Tím, že tato třída dědí od AbstractTransactionalJUnit4SpringContextTests získáváme pro naše testy funkčnost již implementovanou ve Spring frameworku. Jedná se Dependecy Injection, Inversion of Control, Transaction Managment a některé podpůrné třídy Springu.

protected Logger logger = Logger.getLogger(getClass());
protected WordDao wordDao;
protected UserDao userDao;
protected StateDao stateDao;

Definice Loggeru pro logování a dao tříd ijektovaných Springem.

 
  @Resource
  public void setWordDao(WordDao wordDao) {
      this.wordDao = wordDao;
  }

  @Resource
  public void setStateDao(StateDao stateDao) {
      this.stateDao = stateDao;
  }

  @Resource
  public void setUserDao(UserDao userDao) {
      this.userDao = userDao;
  }    
}

A potřebné settery, přes které Spring provádí injektování.

V xml souboru s konfigurací se nachází pouze beany odkazující na implementované dao třídy, beana pro načtení údajů pro připojení k databázi, takzvaná dataSource beana, beana pro načtení konfigurace z property souboru a transaction manager.

Mým úkolem bylo napsat pár testů pro jednu dao třídu, které budou sloužit jako vzor při psaní dalších testů v rámci této aplikace, a ne ji celou pokrýt testy. Proto testovaná třída má pokryto pouze pět metod.

Třídou s testy je WordDaoImplTest, která dědí od výše popsané AbstractDaoTests. Na následujícím kódu popíši část testované metody.

@Test
public void getWordsBySearch() {
    logger.info("Testing getWordsBySearch() ...");

    List<Word> wordList = wordDao.getWordsBySearch(null);
    assertNotNull(wordList);
    assertEquals(wordList.size(), 0);

    wordList = null;
    wordList = wordDao.getWordsBySearch(" ");
    assertNotNull(wordList);
    assertNotSame(wordList.size(), 0);
    assertNotSame(wordList.size(), wordDao.getAllWords().size());

    wordList = null;
    wordList = wordDao.getWordsBySearch("aabbccaabbcc");
    assertNotNull(wordList);
    assertEquals(wordList.size(), 0);
}

Do seznamu slov se přiřazují vždy výsledky hledání. První se bude vyhledávat klíčové slovo null. Předpokládá se, že tento výraz metoda v databázi nenalezne. Seznam slov se ale vytvoří s nulovým počtem položek. Proto se testuje seznam slov na assertNotNull(wordList). Dalším testem je velikost onoho seznamu. Předpokládá se nulová, proto test assertEquals(wordList.size(), 0). Po otestování prvního vyhledávání se přistoupí k testování, kdy se vyhledává ve výrazech mezera. Znovu se testuje, zda není seznam slov null. Dále seznam musí splňovat následující podmínky. Počet položek v seznamu nesmí být 0 a zároveň nemůže být roven celkovému počtu slov. Poslední krajní podmínkou je testování neexistujícího řetězce. Testuje se stejně jako u vyhledávání null.

Odkazy

Retrieved from http://wiki.kiv.zcu.cz/SlovnikTerminologie/TestyJUnit
Content last modified on 02 June 2013, 15:52