Už delší dobu přemýšlím, kdy psát vlastně testy.
Všiml jsem si, že ti, co dělají TDD a píší v nějakém dynamickém jazyku (např. Javascript) mají většinou testy na téměř všechno. To se dá čekat - v Javascriptu kompilátor neřeší skoro nic, takže tam je pomalu potřeba dělat testy i na Hello world. Takže je i pochopitelné, to použití TDD na všechno a pokrytí téměř 100%.
Ale v Javě? Java je staticky typovaná, takže ohromnou spoustu věcí vyřeší již kompilátor. Navíc Java se používá často ve webových podnikových aplikací.
V těch bývá business logiky mnohem méně než zbytku kódu. To znamená, že většinu kódu zabírá čtení a zápis do DB, servírování objektů pro webový framework, případně volání jiných systémů (např. přes webservisy). Takže v podstatě akorát přehazování a transformování informace z jedněch objektů do jiných objektů.
Takže co zde testovat? Selský rozum mi říká, že pouze tu business logiku.
To by ale znamenalo, že TDD se zde použije jen někdy a rozhodně se nedá počítat s velkým pokrytím - maximálně tak na 30%.
Ale já právě od zastánců TDD slyším, že pokrytý mají celý kód. Může mi někdo, kdo doopravdy TDD používá k psaní podnikových aplikací v Javě, vysvětlit, jak tedy správně testovat?
Muzu se zeptat, co pouzivate na testovani cteni/zapis do DB,
jak testujete webove frameworky, pripadne volani jinych systemu v ramci unit testu a kolik let uz takto fungujete a jake mate pokryti funkcionality?
a jak jste tuto cinnost obhajil pri casovych odhadech pracnosti?
a jak jste se domluvil napric tymem, ze toto bude delat kazdy?
Testy v takovem rozsahu jaky popisujete bych nazval spise integracni.
> co pouzivate na testovani cteni/zapis do DB
testuju jestli je na předaný (podvržený) databázový vrstvě zavolaná správná metoda a jestli je sestavenej očekávanej dotaz
> jak testujete webove frameworky, pripadne volani jinych systemu v ramci unit testu
nepsal sem že to dělam, ale šel bych na to stejně jako na komunikaci s databází, tj. zavolá muj kód tu a tu metodu? strčí jí správný data?
> a jak jste tuto cinnost obhajil pri casovych odhadech pracnosti?
třeba že když denně přehazujeme miliony CZK z účtu na účet tak se to musí dělat? případně bych manažerovi sdělil, že netestovat a opravovat pak chyby v produkci je dražší než testovat
> a jak jste se domluvil napric tymem, ze toto bude delat kazdy?
eh, to je spíš otázka na HR
> Testy v takovem rozsahu jaky popisujete bych nazval spise integracni.
snad je z mejch odpovědí jasný že nemůžu souhlasit, ale jinak integrační testy samozřejmě provozujeme taky
diky.
Pro testovani db vrstvy pouzivate nejaky framework, nebo mate vlastni reseni?
ja jsem pouzival dbUnit, problem byl ten, ze jsem byl jediny, kdo chtel testovat i interakci s databazi.
Vytvoril jsem si testovaci data, pomoci db unit "naplnil" testovaci databazi
a provedl test. Pak jsem porovnal data v testovaci databazi oproti ocekavanemu
obsahu, opet pomoci dbUnit.
Ve chvili, kdy jsem mel uz vetsi mnozstvi testu, tak pri zmene datoveho modelu dalo docela dost prace testy udrzovat. Obzvlaste za situace kdy ostatni povazuji testy za dobrou ale ne nutnou vec ...
jak sem psal, testujeme jen SQL na úrovni stringů, teda na úrovni unit testů
integrační testy máme takový povahy, že si ty data prostě ve scénáři vyrobíme, v něm je používáme a kontrolujeme a dál se s nima nic neděje; takový data se pak dají používat i při ručním testování (což byl jeden z důvodů proč nám to zákazník zaplatil)
odpověď na otázku kde má testování smysl je dost individuální sama o sobě, sečteno s nákladama, mínus úspory na hašení problémů v produkci, roli taky hraje jak se na to kouká zákazník; buď je mu to jedno ale zaplatí to, nebo to vyžaduje, nebo to nechce platit, ale nechá se obrat jinak, třeba tak že budeš se svým produktem mít vynikající pověst a přiklepne ti navrch jinou zakázku; prostě to není černobílý
v tvým případě to můžeš buďto vzdát, nebo táhnout tu káru sám dokud praxí nepřesvědčíš ostatní že je to užitečný; když pudeš podesátý za tim samým člověkem a řekneš mu že to zase rozbil, tak se nad sebou možná zamyslí
měli sme tu borce kterej měl odpor i k unittestům a ani nechtěl trávit deset sekund před každým commitem (nebo aspoň pushem) jejich spuštěním, jednou přiběhl s očima navrch hlavy, že mu existující testy zachránili prdel, protože by jinak pushnul nějakej strašnej průser
ad ty otravný změny v databázi - to je život, můžeš se aspoň snažit co nejvíc skrejt změny před databází; pokud máš databázový schéma nějak reprezentovaný v databázi, tak můžeš existující data třeba nechat automaticky doplnit, testy buď selžou ..., ale to už si hodně vymejšlim, protože nic takovýho neprovozuju
>> a jak jste se domluvil napric tymem, ze toto bude delat kazdy?
> eh, to je spíš otázka na HR
To nie je na HR. To je seriozny problem, ktory musi brat do uvahy clovek zodpovedny za vyvoj. Povedzme, ze najmes 10 ludi s tym, ze dopredu povies, ze sa ide TDD. Ak budes mat stastie, mozno 2 z nich budu take tie talentovane, nadane, priekopnicke typy, ktore tej metodike naozaj veria. Dalsi 2 si povedia "preco nie" ale bez dozoru nad sebou by to kedykolvek opustili. Tomu zvysku na tom nebude zalezat vobec a kaslu na cele TDD. Inak to ale vobec nemusia byt zli programatori. Vzdas sa inak sikovnych ludi? Vyssia casova alebo financna efektita TDD sa lahsie obhajuje na papieri ako v skutocnosti. Svet nie je taky idealny, ze sa ti testy rozbiju len kvoli chybe.
... cim popries zakladne myslienky TDD. Miesto inkrementalneho dizajnu prejdes k up front dizajnu, male krocky nahradis velkou neustrazitelnou nefungujucou gucou testov, ktore budu rozbehavat podla velkost modulu tyzdne alebo mesiace. Ked bude chciet niekto refaktorovat kod, bude bud musiet narusit "specifikaciu" tych dvoch geniov. A ti dvaja najschopnejsi ti max. do roka a pol odidu, lebo si im dal robit namiesto TDD toto. A pravdepodobne nikto s timu ich nebude chciet nahradit, lebo, priznajme si, pisanie testov pre ostatnych nikto nebude brat ako povysenie.
Objekty transformujeme obvykle Dozerem (nebo něčím podobným). Takže ok, beru, konvertory Dozeru je třeba otestovat (ale to i děláme).
Samotné transformování (mapování) teda netestujem. Možná bychom asi měli, ale budem psát kilometry a kilometry testů, kde jen budem vyjmenovávat vlastnosti bean...
Urcite jeste testovat tu komunikaci s DB, jednoduchou upravou datove vrstvy s testem, co je ve (fake-DB) pred provedenim nejake business operace a co po provedeni. dtto komunikace webovy framework-business vrstva.
A zrovna u toho weboveho frameworku a vrstev nad nim uz se vetsinou ztraci vyhoda prekladace Javy se statickym typovanim - tedy nevim, jaky framework konkretne pouzivate, ale vetsinou to tak je, ze se kusy kodu pisou do kdovijakych templatu co se mozna nekde nekdy ztransformuji a prekladaji...
„Java je staticky typovaná, takže ohromnou spoustu věcí vyřeší již kompilátor.“
To je hodně rozšířený mýtus, že statické typování vyřeší spoustu chyb. Nevyřeší, vyřeší POUZE typovou správnost. Jestli je hodnota v rámci typu v pořádku, nezjistí, přičemž to je značný prostor pro chybu.
„Navíc Java se používá často ve webových podnikových aplikací. V těch bývá business logiky mnohem méně než zbytku kódu.“
Technologie klientu (lehký/těžký/jiný) nemá na doménovou logiku vliv, ta je jen jedna.
„Takže v podstatě akorát přehazování a transformování informace z jedněch objektů do jiných objektů.“
Doménová logika vždy pouze přehazuje a transformuje informace mezi objekty! (Bavíme-li se o objektovém modelu.) Co by měla dělat jiného?
„Takže co zde testovat?“ Testovat se dá všechno, otázkou je jen, zda je to třeba.
"To je hodně rozšířený mýtus, že statické typování vyřeší spoustu chyb".
Presne tak. Enterprise Java je v podstate dynamicky typovany jazyk - i kdyz nema "eval". V JEE je prakticky kazda instance nejaka dynamicky generovana proxy trida. Navic se pouziva dependency injection a kontejner aplikacniho serveru vam inicializuje atributy trid sam.
Navic v "moderni" Jave mate znacnou cast aplikacni logiky v XML metadatech (popr. v anotacich). Dneska uz ani programator nema sanci ze zdrojaku zjistit co bude dana aplikace delat.