Alapvetoen nem azt akarjuk tesztelni, hogy egy adott implementacio hogyan oldja meg a feladatot, hanem arra vagyunk kivancsiak, hogy adott bemenetre a vart kimenet jon-e. Az osszes tobbi csak sallang, boilerplate, szuksegtelen. Alapvetoen interface-re kellene irni a tesztet, hiszen nem az implementacio az erdekes szamunkra, hanem az altala nyujtott funkcio.
Nyilvan szuksegunk van mock objektumokra, hiszen az eles osztalyt behuzalozni meg nagyobb szenvedes lenne, es akkor mar nem csak a unitot teszteljuk. Akkor meg megis hogy lehetne elhagyni?
Ahogy fentebb is emlitettem, a teszt az adott unit viselkedeset irja le bizonyithatoan helyesen. Mig a mock objektum egy altalunk meghatarozott, az eredeti viselkedessel nem feltetlenul azonos viselkedessel rendelkezik. Ez veszelyforras. Adhatok at egy ures listat egy metodusnak, ami listat var anelkul, hogy beleneznek a dokumentacioba, majd mar csak az integracios tesztnel derul ki, hogy jahat arra IllegalArgumentException-t dob.
Tehat a mock nehezkes es veszelyes. Viszont vannak tesztjeink, amik bizonyithatoan helyesek. Miert ne hasznalhatnank oket mock objecteknek? Hiszen arrol van szo, hogy a tesztben leirjuk, hogy (mivelhogy pure functionoket hasznalunk), hogy "ilyen bemenetre olyan kimenetet adj vissza". Ha megforditjuk, "itt egy bemenet, adj egy kimenetet", akkor meg is kaptuk az eredeti fuggvennyel megegyezoen viselkedo mock objectunket.
Azt nyilvan lehet ellenervkent felhozni, hogy B osztaly A-nak adott implementaciojara keszult fel es ha valtozik az implementacio, az mar nem ugyanaz a unit teszt, ujat kell irni, vagy hogy ez mar inkabb integracios teszt, de ezzel nem ertek egyet. Ugyan tekinthetunk ugy is unit tesztekre, hogy adott idopillanatban ervenyes viselkedest irjuk le egy idealizalt kornyezetben, de ez nem hatekony es nehezen karbantarthato, nem mellesleg elvonja a lenyegrol a figyelmet.
El kell hagynunk a mockokat es jobbat kell talalnunk helyette. Meg kell talalnunk a modjat, hogy a tesztjeink masoknak mock-kent felhasznalhatoak legyenek. Ha a teszt es a mock ugyanaz, akkor minel tobbet hasznaljak a mockunkat (tesztjeinket), minel tobb mock esetet (teszt esetet) adnak hozza a meglevokhoz, annal inkabb biztosak lehetunk nem csak az adott unit, de az egesz rendszer mukodokepessegeben.
Lehet, hogy nem mindenhol megvalosithato ez. Biztos van olyan kodbazis, olyan eset amikor ez az ut nem lesz jarhato. Pl. IO-t mindig mockolni kell majd. Lehet, hogy uj paradigmakat kell kitalalni es uj best practiceket. Eloszor csak kicsiben lehet elkezdeni, de ahogy egyre elterjedtebb lesz, ugy lesz egyre konnyebb tesztet, jo, megbizhato tesztet irni. Ami eddig csak szenvedes volt, az onnantol kezdve a leghatekonyabb eszkoz lesz, onmagat erositoen eredmenyezne jobb kodminoseget.
- Hevi blogja
- A hozzászóláshoz be kell jelentkezni
- 1487 megtekintés
Hozzászólások
Mock és Stub nélkül is meg lehet oldani a tesztelést, csak máshogy (jól) kell terveznünk a kódot.
Részletek ebben a blogomban találhatók: Mock & Stub, avagy hogyan tesztelünk rosszul tervezett kódot
- A hozzászóláshoz be kell jelentkezni
Edit: kozben latom a tobbiek kommentjeit is, szoval atmozgatom a hozzaszolast korrektebb helyre :)
- A hozzászóláshoz be kell jelentkezni
Nagyon jó gondolatok vannak a blogodban és alapvetően egyetértek vele.
Az általam linkelt blogban szereplő videóban is felmerülnek hasonló gondolatok, érdemes megnézni.
A blogomban szereplő hozzászólásokat is érdemes elolvasni, mert sok okos gondolat van benne.
Nézzük most ezt a blogot részletesebben!
A mockokat ki kell dobni a fenebe. Karosak. Nehezkes oket felsetupolni. Minden egyes dependencia hivashoz meg kell adni a viselkedest. Implementacio fuggove teszi a tesztunket.
Pontosan, egyetértek teljes mértékben!
Viszont vannak tesztjeink, amik bizonyithatoan helyesek. Miert ne hasznalhatnank oket mock objecteknek?
Azért, mert tulajdonképpen azok is mock-ok és egyáltalán nem igaz, hogy bizonyíthatóan helyesek lennének. A bizonyítás nélküli helyesség is csak akkor lenne igaz, ha lenne rájuk teszt írva (teszt a tesztre).
El kell hagynunk a mockokat es jobbat kell talalnunk helyette.
Így van, van is rá megoldás, csak ahhoz másféleképpen kell terveznünk, felépítenünk a kódot. Tehát az nem megoldás, hogy ugyanaz a kódunk marad, csak más mock-ot használunk.
Pl. IO-t mindig mockolni kell majd.
Azt sem kell mockolni, egyrészt lehet fake-elni, másrészt áttervezéssel a legtöbb helyről ki lehet szorítani, egészen a legfelső szintig.
Lehet, hogy uj paradigmakat kell kitalalni es uj best practiceket.
Igen, ez a megoldás, a videóban ad is egy pár példát erre.
- A hozzászóláshoz be kell jelentkezni
Szerintem amiről írsz az létezik.
Amit én ebből a cikkből megértettem, hogy kétfajta vallás/iskola létezik ha Unit tesztelni akarunk.
Az egyik amiről írod, hogy nem jó és nem tetszik a "Mockist Testing", a másik pedig ami neked tetszene az a "Classical Testing".
Ajánlom az egész cikk végigolvasását, mert hiánypótló a témában! :)
- A hozzászóláshoz be kell jelentkezni
Ket dolgot ajanlok figyelmedbe:
http://rbcs-us.com/documents/Why-Most-Unit-Testing-is-Waste.pdf
(masodik resz: http://rbcs-us.com/site/assets/files/1191/segue.pdf)
Elsore fejen ut, de minel tobbet agyalok rajta, annal inkabb igazat adok Jim Coplien-nek. Annyira, hogy lassan komoly osszetuzesekbe keveredek a kollegakkal, akik abszolut TDD maniasok, es imadjak a tautologikus unit teszteket.
A mockoknak abban van szerepuk szerintem, hogy uzleti funkciokra levalasztva tudod (funkcio/integracio) tesztelni a modulodat. Vagyis, peldaul tesztelned az authentikaciot, hogy 10 sikertelen belepesi kiserlet utan lockolja az accountot. Tegyuk fel, hogy ez az authorizaciot nem erinti. Igen, de az authentikacio es az authorizacio altalaban egy blokkban van, nehez kulon tesztelni - ezert van a mock, ami az authorizacios reszek helyett fut (peldaul a jogokat egy masik adatbazis tarolja, vagy sok plusz extra informacio kell peldaul a user-group hierarchiarol), az authentikacios tesztek viszont amennyire lehet, a valoshoz hasonlo kornyezetet kapnak, peldaul valos adatbazis helyett in-memory verziot.
Ezt viszont nem ertem: "Viszont vannak tesztjeink, amik bizonyithatoan helyesek."
Mennyivel konnyebb a tesztrol bizonyitani, hogy helyes, mint a kodrol? Adott esetben meg nehezebb is... Tovabb rontja a minoseget, ha a tesztet ugyanaz irja, aki a kodot (ez ugye eleg sokszor elofordul), igy a tesztek - foleg a tautologikus tipusu unit tesztek - altalaban onigazolo jelleguek, tenyleges informaciot nem hordoznak, csak a kodmeretet novelik.
- A hozzászóláshoz be kell jelentkezni
Ezekről sok szó volt a Fejlesztés esetén jobbnak tartom ... szavazásnál is.
Köszi a videót!
- A hozzászóláshoz be kell jelentkezni
Koszi szepen mindenkinek, mostmar tenyleg raszanom magamat egy belsos eloadasra, mert mar elegem van belole, hogy mindenki a unit teszteket nyomatja, az en allaspontomat meg nem ertik meg, mert a komplex temat kis adagokban nem lehet atadni. Szoval most azt hiszik, hogy azert utalom a mockokat, mert nem ertek a teszteleshez, a csapatom meg elkuldott TDD eloadasra is, hatha meggyoznek :)
Irtam is nekik Slack-en, hogy tok jo, hogy elkuldtetek, eddig semmiben nem mondtak nekem ellent... meg azt se gyoztem hangsulyozni, hogy nem a unit tesztek, meg a TDD, hanem a mockok ellen vagyok.
Ugyan nem olvastam meg vegig az osszeset, de azert megnyugtato, hogy masok is ezen a velemenyen vannak, illetve jo forras lesz az eloadashoz, nem kell mindent fejbol leirkalnom :) Mondjuk valoszinuleg lesz egy-ket dolog, amit mashogy kepzelek majd el a tobbiekhez kepest, na meg arrol se art szot ejteni, hogy egy hogy jon ossze clean code-dal, hogy erdemes felepiteni egy projectet, hogy jol tesztelheto legyen, hogy az IO-t kell mockolni (en meg a Date-et is ide sorolnam, az is egy syscall az OS fele altalaban), mast nem,
Hogy az IO mockolas segitsegevel hogy tudjuk megvalositani a 100%-os verifikaciot. Minden almom az, hogy a kod belso szerkezetet is BDD szeruen (a lenyeget tekintve, termeszetesen nem akarok Gherkinnel szorakozni, API tesztelesre amugyis szornyu volt) lehessen tesztelni, ahol az szamit, hogy mit csinal a fuggveny, nem az, hogy hogyan csinalja.
Ezzel baromi konnyen meg lehet valositani olyan teszteket, hogy "ez a kiindulo feltetel, ezt csinaljuk, ennek ez az eredmenye, ekozben ilyen interakciokat varok a kulvilaggal...".
Erdekel az, hogy egy Service-t hivott meg a fuggveny, vagy egy Facade-t? Nem. Erdekel, hogy az adatokon milyen konverziot vegez? Nem.
Mi erdekel? Az, hogy mi lett a vegeredmeny, es kozben milyen hatasok tortentek a kulvilagra. A belso folyamatok tok nem lenyegesek. Black/white box teszt az igazi :)
- A hozzászóláshoz be kell jelentkezni
A belso folyamatok tok nem lenyegesek. Black/white box teszt az igazi :)
Ha nem lényegesek a belső folyamatok, akkor csak black box teszt az igazi, mert a másik pont a belsőt teszteli.
- A hozzászóláshoz be kell jelentkezni
White-box testing can be applied at the unit, integration and system levels of the software testing process.
https://en.wikipedia.org/wiki/White-box_testing
Nincs azzal se gond. Ha megfeleloen van felepitve a kodbazis, akkor igazabol minden osztalyt/metodust is le lehet tesztelni, ugyanugy, mintha unit teszt lenne, csak annyi a kulonbseg, hogy az IO-n kivul mast nem mockolunk.
Ezzel megorizhetjuk a unit tesztek nagy elonyet, azt, hogy pontosan mutatjak hol torik a kod. (Szerk: ehhez nagyon jol jonne, ha lenne olyan teszt framework, ami eloszor felepiti az object/call fat/graphot es utana alulrol felfele kezdene el tesztelni. Igy rogton meglenne az az elso integracios teszt ami torik, nem kellene keresgelni se). Nyilvan ennek nagyobb a karbantartasi igenye, mint egy tisztan black-box (BDD) tesztnek, viszont sokkal kisebb, mintha mindent mockolnank.
Ezzel a megoldassal lesz amugy annak ertelme, hogy a tesztek gyakorlatilag az adott fuggveny elo dokumentacioja, mert a figyelmet nem viszi el az implementacios reszlet, azaz a mockok, hanem annak a viselkedesere tud a teszt koncentralni.
- A hozzászóláshoz be kell jelentkezni
A White box teszt az az implementációt teszteli, mit hogyan csinál az adott kód.
Ellentétben a Black box teszttel, ami az teszteli, hogy milyen bemenetre milyen kimenetet ad válaszul.
Mind a két tesztet lehet a tesztelés bármelyik szintjén alkalmazni.
- A hozzászóláshoz be kell jelentkezni