Je, ugy tudtam, nalad osszemosodik a unit es az integration teszt fogalma, pont azert probalom en is egyszerre kezelni oket (bar megmondom oszinten, egy kicsit nehez), mert azt mondtad, egy jo alkalmazasnal ossze lehet oket mosni. Most akkor megiscsak kulon kellene kezelnem az unit teszteket az integration tesztektol, vagy hogy van ez?
Ami a 4 product-os peldadat illeti nagyon egyszeru (most keltem, nem vagyok hajlando utananezni a konkret kodnak, de gondolom ennyibol is megerted): egyszeruen kistubolom az MNBService.exchange() (figyelem! NEM az MNBExchangeService.exchange()-t!) fuggveny hivasat a teszt setup() -jaban ugy, hogy egy fix rate-tal szorozza fel az inputkent kapott arat. Hogy ez miben jobb, mint a te implementaciod? Technikalilag semmiben, csupan annyiban, hogy nem kell egy plusz osztalyt karbantartanom, illetve ugyanaz az osztaly (MNBExchangeService) kerul felhasznalasra, mint ami az alkalmazasban, vagyis ha a MNBExchangeService.exchange() fuggvenyben valami strukturalis baki van, az ki fog bukni, az MNBService.exchange() meg ugysem az en kodombol jon, azt nem nekem kell lefedni tesztekkel.
Megegyszer, lassan leirom, hogy megertsd: nem a modularizacioval van elsosorban a gond, az jo dolog. A rossz dolog az az, ha nem teszteljuk a konkret implementaciot arra, hogy jol mukodik-e. Az MNBExchangeService eseteben igenis az elvart mukodes resze az, hogy belehivjon az MNBService-be, es ha ezt nem teszi, elvarom a teszttol, hogy hibat dobjon, mert engem nem az erdekel, hogy random szamokat vissza tud-e adni, hanem az, hogy az MNBExchangeService tenyleg az MNB megfelelo webszervizet hivogatja, es nem a holnapi lottonyeroszamokat sorolja vissza valaszkent. Az alkalmazas szempontjabol ugyanis nem elegseges az, hogy az MNBExchangeService.exchange() szamok beadasara szamokkal valaszol-e, hanem az is fontos tenyezo, hogy ezek a szamok hogy allnak elo. Mivel a kulso gyarto service-be gyakran koltseges belehivni (akar financialisan akar a futtatas idokoltsegevel szamolva), ezert a unit teszt eseteben a gyarto altal biztositott API feluletet ki lehet mockolni es stubolni, mert nem szempont az, hogy tenyleg kihivjunk az MNB szervizebe, az a szempont, hogy az implementacio megtenne-e.
"Stub esetén se a valós működést teszteled, hiszen a valós service hívást kistubolod."
Itt azonban nem az MNBExchangeService kistubolasarol beszelunk, hanem a gyarto altal adott MNBService kistubolasarol, ami adott esetben nem para, ugyanis az MNBExchangeService-tol a unit teszt szintjen csak az az elvaras, hogy az MNBService-t hasznalja a szamok eloallitasa soran, es hogy a megfelelo atalakitasokat vegezze, de nem elvaras, hogy a mindenkor aktualis USD-HUF arfolyam mentsen valtson, az mar a rendszer/integration teszt feladata.
Tehat, amire itt probalok rautalni, es amit te nagyvonaluan kikerultel a sajat peldadban, az az MNBExchangeService unit tesztje, amit nem lehet kihagyni, hiszen ez az, amivel az alkalmazas valojaban dolgozik. Ezt az osztalyt nem eleg csak a rendszer/integracios tesztek szintjen lefedni, mert az adott esetben pontatlansagokhoz is vezethet, illetoleg fontos szempont az, hogy ezek a tesztek sokkal ritkabban futnak, mint a unit tesztek, vagyis nagyobb az eselye, hogy sokaig hibas koddal zorog a szeker.
Es meg egy fontos dolog: azert is erdemes minel tobb tesztben, minel tobb kornyezetben hasznalni az MNBExchangeService-t, mert ha nem ilyen egyszeru az implementacioja, hanem tobb allapottol is fugg az uzleti logika, ami hajtja, akkor jobban ki tud bukni, hogy hiba van, attol fuggetlenul, hogy ez egy masik teszt soran bukott ki. Ugyanis az, hogy ha egy teszt soran kibukik, hogy egy, a teszttol egyebkent tobbe-kevesbe fuggetlen ponton hiba van, az mindig jo, ugyanis a teszt olcso, de ha ugyanez a productionben jon ki, az eleg draga tud lenni mindenki eleteben. Raadasul a tesztek kodja mindig egyszerubb a vegleges alkalmazas kodjanal, azt debugolni is sokkal konnyebb (meg a mockokkal/stubokkal egyutt is), mintha az aktualis kodot kellene debugolgatni.
--
Blog | @hron84
Üzemeltető macik