Slow Legacy Tests
A Working effectively with Legacy Code alapján a testnek gyorsnak kell lennie. Ha egy test tovább tart, mint fél másodperc, akkor az lassú. Ugyan extrém megszorításnak tűnik, de ha jobban belegondolsz, akkor nem az. Ha van egy szép nagy egészséges test halmazod, amit igen jól tudná ellenőrizni a rendszert, akkor mi az egyetlen dolog, almi megakadályozhat abban, hogy használ: csak a sebesség.
Én nem teszek nagy különbséget unit és gyorsan lefutó integrációs teszt között.(integrációs teszt nekem többnyire azt jelenti, hogy adatbázist buherál). Igaz, hogy az integrációs tesztek lassabbak, mint a valódi unit tesztek, de még így is beleférnek a fél másodperces limitbe.
Alapvető, hogy egy integrációs tesztet is fel lehet gyorsítani in-memory adatbázissal, vagy gyors kapcsolata és jó teljesítményű igazi szerverrel. Tudom, hogy egy szerverrel sérül az teszt izoláltság, de én eddig csak olyan munkakörnyezetben dolgoztam, ahol az adatbázis szerver a környezet része (vagy karbantartott központi, vagy lokális gépen futó)
Mitől lehet lassú?
- Spring test: A Spring context felállása meglepően sok ide. Az én esetemben a legtöbb idő a Hibernate miatt veszítjük el. (még egy fekete pont a Hibernet-nek). De a Spring elég okosan oldotta meg, mivel újrahasználja már inicializált kontextust. Egy kezdeti nagyobb startup költség után a db alapú tesztek is igen szép tempóban futnak. Nálam egy remote Oracle adatbázissal elég gyors tesztjeim vannak, de..
- Subprojects: Sok-sok subproject esetén már nehéz kihasználni a Spring startup erejét. Jelenleg olyan sok alprojecttel dolgozom, hogy nem fér ki az Eclipse projectlistára görgetés nélkül. És rengeteg alproject egyszerűen nagyon kicsi (kevesebb, mint tucatnyi osztály). És ebben a környezetben a Spring minden alproject esetén újrainicializálja a kontextust, mivel nem tud mit tenni. Ekkor már a sok összeadódó startup költség is jelentős tényező. Igaz, hogy jó ha felbontjuk komponensekre, de lehet kompromisszumokat kötni. Komponensekre bontásra még az alap java package struktúra is jó. Másik alternatíva lehet, hogy nem minden projectnek lesz saját integrációs tesztje, hanem egy közös integrációs teszt projectet állítunk fel és azzal dolgozunk.
- Adatbázis alapú teszt, ahol nem is kell: Fejlesztői lustaságból több olyan teszt is van, ami csak azért használ adatbázist, mert a fejlesztő lusta volt (vagy éppen nem tudta hogyan kell) tesztadatokat generálni stubokba. Ez a lépés még a teszt izoláltságot is sérti.
-
SQL szintaxis ellenőrzés:
Legtöbb adatbázis alapú tesztünk igazából csak SQL szintaxist és alap szemantikát (ott vannak a táblák és az oszlopok) ellenőriz. Ha standard SQL dialektust használsz, akkor in-memory adatbázisokra is lehet hagyatkozni. De platformspecifikus, agyon-optimalizált lekérdezések esetén ez nem járható út. Másik megoldás, ha elemzed a lekérdezéseket. Ha olyan a lekérdezés, amiben van egy dátum intervallum keresés (e.g.
between
), akkor szépen paraméterezd fel a távoli jövőbe és, akkor az adatbázisod nem fog adatokat lapozni (megfelelő indexelés mellet), csak a szintaxist ellenőrizni. - Extrém drága lekérdezések: SQL szintaxis ellenőrzés keretében olyan tárolt eljárásokat is meghívunk, amik extrém sokáig futnak (igazából éjszakai job-okban futnak). Itt kompromisszumot kell kötni. azt akarjuk, hogy biztosak legyünk abban, hogy egy paraméter nélküli tárolt eljárást meg tudunk hívni, vagy spórolunk pár (sok) percet.
Summa: viszonylag kis kompromisszumokkal lehet gyors integrációs teszteket írni.