Doporucuji Growing object oriented software guided by tests. Jedna z nejlepsich knih, kterou jsem o TDD cetl.
http://www.growing-object-oriented-software.com/
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.
Nejak mi chybi vysvetleni, proc nepouzivat JUnit, ktere je integrovane temer v kazdem IDE. Navic pouzivat automaticke testovani bez nastroju, ktere zobrazi code coverage, je docela o nicem, protoze tak clovek nema poradne jistotu, ze je testovano uplne vse, co by testovano melo byt. A posledni pripominka: Proc, sakra, autor pouziva nazvy trid zacinajici malym pismenem?
Podla mna tiez - "ten klasicky" assert sa pouziva na overenie, ci mi v ramci mojho modulu chodia pripustne odpovede. Asserty su zapnute stale pocas "bezneho" testovania a mimoprodukcneho behu systemu. To znamena, ze ked niekde (interne) pouzivam nejaky objekt, tak takmer vzdy automaticky na zaciatok kazdej metody s nim napise nieco ako assert obj != null;
Ked mam iny predpoklad dany logikou aplikacie, tak ho dam do assertu - to v produkcii nic nestoji a vyrazne to ulahci debug.
Tento assert nie je o tom, ze by sa pustal ako testy - sluzi na to, aby program spadol co najblizsie chybe. U Javy je sice pekny backtrace, ale prechadzat 20 funkcii, cez ktore sa to predavalo, zaberie ovela viac casu ako 20 "automatickych" riadkov.
Assert ma podla mna pokryvat vsetky "ocakavania" vnutri jedneho API. (Ak to je nieco mimo API, tak hadzem vhodnu Exception).
Testy oproti tomu pokryvaju len velmi male casti kodu. V nich snad vobec nema zalezat na assertoch (aky zmysel by toto tu napisane malo bez zapnutych assertov?). Ak si niekto z pre mna nepochopitelnych dovodoch chce robit testy mimo JUnit, tak tam by som namiesto assertov asi skor throw novej Exception, ktora bude podedena od java.lang.RuntimeException.
Ja obycajne pisem 2 nezavisle testy (co do testovanych parametrov) pre kazde ocakavane chovanie. Vyhody su snad jasne - ked sa nieco rozbije, tak sa to casto rozbije tak, aby to cez 1 test zhodou okolnosti preslo. Niekto sa tu pytal, ze preco? Ja to robim preto, lebo mi to hned ukazuje pouzitelnost mojho API (tam, kde ho mam), problemy s nim pri implementacii, robi to ukazku jeho pouzitia a zaroven to odchyti velku cast programatorskych chyb.
Také to vypadá, že autor žádné IDE nepoužívá, jinak by k tomu, aby zjistil, že třída neexistuje, nemusel kompilovat, ale viděl by to hned. Zřejmě také ještě neobjevil klíčové slovo import, jinak by snad nenapsal takovou hovadinu, jako že kompilátor sám někde najde nějakou tridu stejného jména. To leda by se autor náhodou strefil svým balíčkem zrovna do nějakého existujícího na jeho classpath, ve kterém by náhodou byla stejnojmenná třída.
No nemá cenu se rozčilovat, jdu raději spát. Jen mě překvapuje, že na root.cz, který jinak považuju za kvalitní web, pustí takovouhle hrůzu.
Používat IDE je povinnost?
Záměrem článku bylo vysvětlit, proč se mají psát nejprve testy a pak teprve produkční kód. Ukázky musí být co nejjednodušší, aby se to z toho dalo pochopit.
Klíčové slovo "import" samozřejmě znám a také vím, že kompilátor má i defaultní "import".
Článek není o IDE ani o importech. Je o TDD.
Článků na JUnit je dostatek. Tento článek má motivační účel pro ty, kteří si chtějí TDD vyzkoušet a neví jak na to. Článek není určen pro spokojené uživatele JUnit.
Názvy tříd začínající velkým písmenem používám. Jen testovací třídě jsem dal předponu "test". Není to produkční třída, ale testovací. Tu je možné napsat jakkoli, na kvalitu kódu se nehledí.
Kvalita kodu v testovacich tridach je esencialni. Kdyz pisete nejakou prkotinu jako v takovemto clanku, tak to neni videt. Kdyz programujete nad codebase, co ma desitky/stovky tisic radku kodu, tak je to poznat.
Samozrejme palti vetsina pravidel, co plati pro produkcni kod (pojmenovavaci konvence, don't repeat yourself, spravna a citelna pojmenovani, co testuji jen jednu vec). A pridavaji se k nim i pravidla specialni typu testuji-li metodu foo(Baz[]) v tride Bar, tak bude testovaci kod v takove a takove tride (vetsinou TestBar) a v takove a takove metode (nekdy testFoo(), jindy trebas metody testFooFoes(), testFooAcceptsEmptyArray(), fooFailsForNull()... Existuji i jine konvence, je nutne je v teamu dohodnout.)
> Kvalita kodu v testovacich tridach je esencialni
TDD mantra podle Becka: red, green, refactor
já teda refaktoruju testy až když uznam za vhodný, tj. klidně hned, ale když je to nějaká prkotina kterou (zatim) nezrecykluju, tak na to ani nemusí dojít
ale nemluvim o konvencích v pojmenování, ale o kvalitě kódu testů
To mi pripomina jak mi BLEK jednou rikal jak jednou vyhral nejakou programovaci olympiadu tim, ze misto aby implementoval zadani, implementoval pouze to aby to proslo testem overujici spravnost.
Vsiml si totiz, ze pro vysoka vstupni n je pravdepodobnost, ze program vrati "ANO" extremne nizka, a tak tam zadratoval, ze to od urciteho n vrati fixne "NE" cimz se rychlost vypoctu extremne zrychlila a diky tomu to vyhral. Pravdepodobnost ze bude vadnost programu odhalena pritom byla velmi nizka.
Pride mi to naprosto genialni - dle meho nazoru BLEK totiz spravne pochopil, ze cilem programovaci olympiady neni napsat nejlepsi program, ale proste tu olympiadu vyhrat.
Kamarad kdysi takto taky vyhral nejakou programatorskou soutez. Meli za ukol na strojich nainstalovanych v labu (tam se to i testovalo) implementovat nejaky (alespon) hodne primitivni textovy editor a zatimco se ostatni hodiny a hodiny drbali se ctenim klavesnice, implementaci gap bufferu (tedy ti, co ho znali) atd. atd., tak kamos jen pres exec() zavolal edit.com a bylo hotovo = zadani splneno za 10 minut, navic tim nejlepsim zpusobem (!NIH)... :)
Test-driven development je jenom taková hračka pro Java konzultanty a v praxi je jenom omezeně použitelné. Dá se použít nejvýše na jednoduché funkce, jako třeba šifrování nebo konverze dat, ale na běžné aplikace je to zcela mimo. Důvodem je fakt, že složitost i průměrné aplikace je již natolik vysoká, že sestavit pro ně test je tak složité a náročné a časově komplikované, že se rychle ztratí přehled jestli je chyba v aplikaci nebo v testu a to pak ztrácí smysl.
Nesmysl.
Jednotkove testy nepotrebuji (a nemaji potrebovat!) mit celou aplikaci, k tomu mame mocky, stuby... Pokud nejste schopen ke kusu kodu takovy test napsat, tak to velmi pravdepodobne znamena, ze ten kus kodu je blbe navrzeny.
A pak se samozrejme pisi i testy integracni, ale to je trosku jina historie. Tam se opravdu casto stava, ze neni jasne, zda je chyba v kodu nebo v testu. Ale to obvykle znamena, ze ve skutecnosti ani neni jasne, jak presne zni zadani. A to je duvod k zamysleni nad tim, jakou mate komunikaci se zakaznikem a ne k odmitnuti testovani jako takoveho.
Jinymi slovy: ano, testy vam zerou cas (stejne jako VCS, rucni testovani a dalsi veci, co nejsou kodovani). Ale pokud vam ho zerou neumerne vice nez nakonec usetri, tak je docela pravdepodobne chyba nekde jinde.
Já za to nemůžu že máte problém s pochopením psaného slova. Představte si normální aplikaci, třeba účetnictví Pohoda a teďka si představte jak to budete testovat pomocí TTD. Netvrdím že to nejde, ale složitost testů bude tak vysoká, že nebudete schopen v reálném čase rozhodnout zda je chyba v kódu nebo v testu. Pochopitelně se test bude skládat z mnoha dílčích testů, to je samosebou.
Pindy o nejasném zadání s tím naprosto nesouvisí.
Testy od určité složitosti aplikace zaručeně žerou více času než kolik je ho k dispozici.
Netvrdím že TDD je úplně k ničemu, ale není to obecně použitelná praktika, tak jak se mnozí Java konzultanti mylně domnívají.
> Netvrdím že to nejde, ale složitost testů bude tak vysoká, že nebudete schopen v reálném čase rozhodnout zda je chyba v kódu nebo v testu.
za předpokladu, že ten test nejdřív konzistentně prochází a pak konzistentně neprochází, je otázkou minut než najdu patch kterej to rozbil a pak otázka dalších pár minut než z toho diffu vykoumam v čem je problém
> Testy od určité složitosti aplikace zaručeně žerou více času než kolik je ho k dispozici.
a kolik je ho k dispozici? kolik je k dispozici peněz který se propálí na opravách chyb v produkci (smluvních pokutách, hledání novýho programátora když ten starej znechuceně odešel, atd.) protože netestování umožnilo vypuštění nekvalitního produktu? je jich dost?
IMHO čas nehraje roli, roli hraje to, jestli máš zákoše na svuj software a jestli se ti vývoj vyplatí
Jistě, když už se ti test podaří test sestavit, je to pak jasné.
Času je obvykle k dispozici méně než kolik se věnuje vlastní tvorbě aplikace. Otestovat všechno pomocí TTD spotřebuje násobky času nutného ke tvorbě aplikace. Proto to mnoho softwarových společností řeší přes service packy, kdy se jednoduše zjištěné chyby řeší až v provozu, až na opravdu velké výjimky.
Mám přesně tu samou zkušenost. Na testování, jestli metoda sectiCisla() je opravdu sečte jsou automatické testy fajn. Ale při pokusech o testování složitějších operací pracujících s komplikovanými daty se rychle dostanete do situace, že vám údržba testovacích dat a/nebo mocků zabere srovnatelně nebo i mnohem víc času, než vlastní psaní aplikace. Potom je mnohem jednodušší prostě využít lidské testery.
Ked sa mi pisanie testov zacne zdat narocnejsie ako pisanie aplikacie, tak je to pre mna znamenie, ze je nieco zle navrhnute a mal by som si navrh este premysliet.
Ked napisem testy este pred samotnym kodom, tak sa vyhnem neudrzovatelnemu kodu, ktory by musel byt pocas hlavneho vyvoja testovany ludskymi testermi. Ti tam mozu byt, ale skor na take veci, ako je intuitivnost GUI a po skonceni "hlavneho vyvoja" na testovanie zakladnych veci, ktore sa mohli zabudnut pokryt.
Nejde o psaní testů, ale o údržbu testů. Když znáte dopředu kompletní, detailní zadání, tak je to v pohodě, napíšete testy, pak aplikaci. Jenže čím větší aplikace, tím méně detailní a kompletní specifikaci na začátku máte. Takže musíte testy v průběhu programování měnit podle měnícího a doplňujícího se zadání a to je právě ta náročná a pracná část.
Udrzba testu dela drazsi samotny vyvoj (a predelavky), ale ve vysledku to stejne vyjde levneji, nez banda testeru, kteri by museli testovat cely program idealne porad (rekneme 20 vetvi, build 1x denne). Cili ten drazsi jednorazovy vyvoj/predelavka se v podstate vrati behem nekolika dni. Mluvim ted o realne aplikaci ktera je ve vyvoji pomalu 20 let, cili o nejake znalosti zadani dopredu nemuze byt rec. Detaily viz muj prispevek nize...
20 vývojových větví? To máte 20 verzí pro různé zákazníky, každou s jeho vlastími customizacemi? Ano, tam mohou být automatické testy docela užitečné a pokud děláte takovou aplikaci, tak chápu, že máte takové zkušenosti, jaké píšete.
Když, na druhou stranu, máte jen jednu verzi aplikace s relativně dlouhým vývojovým cyklem, na jehož konci se musí tak jako tak pořádně ručně přetestovat, tak jsou automatické testy mnohem méně užitečné a investovat do nich se vyplatí o to méně. Takové jsou zase moje zkušenosti.
A ještě jeden rozdíl mezi námi je. Já si nemyslím, že člověk, co má rozdílné zkušenosti je má nutně proto, že je blbec.
Přijde mi, že se tu míchají dvě věci dohromady
1) jednotkové vs. komplexnější/systémové/integrační testy
2) ruční vs. automatizované testování
Co se týče 2, jsem ve většině případů pro automatizaci – i když ten vývojový cyklus (než se dá produkt zákazníkovi) bude delší, stejně je dobré si dělat svoje iterace a testovat co nejdříve po tom, co bylo naprogramováno → máš čas to opravit, práce pro testery je průběžně, při případných opravách si programátor dobře pamatuje, o co šlo (dělal na tom před pár dny, ne před pár týdny nebo měsícem).
Co se týče 1, je to mnohem víc diskutabilní. Komplexní testy být musí, ať už automatizované nebo ruční. Ale jednotkové – jak už jsem tu psal, nemají s kvalitou z pohledu uživatele moc společného, je to pomůcka pro vývojáře – jsou pro zákazníka/uživatele irelevantní. To ať si zváží každý tým/projekt, zda se vyplatí a zda to usnadní/zlepší vývoj, nebo zda to bude jen házet klacky pod nohy a bude to zbytečně zabitý čas kvůli formalitám a 100% pokrytí (100 % zeleně podbarveného kódu není zárukou vůbec ničeho).
Je to jedna aplikace, jedna verze ktera je u zakazniku (s relativne dlouhym vyvojovym cyklem), mezi verzemi vychazeji pouze opravy. Na kazdou novou vlastnost i na opravy se zakladaji nove vetve, po kazdem buildu v kazde vetvi behaji testy (radove tisice), kazda odchylka se resi. Kriteria pro zacleneni do hlavni vetve jsou pomerne prisna, samozrejme vcetne splneni vsech testu, rucniho otestovani a pridani novych testu do systemu na nove vyvinute veci.
Chapu vasi namitku ohledne "všechny aplikace mají stejné vlastnosti, jako ta jejich", take nemam takove zobecnovani rad, ale zkuste mi odpovedet na nasledujici: cekal bych, ze cim slozitejsi aplikace, tim komplexnejsi budou vstupy a vystupy i vnitrni logika. Predstavte si, ze behem rocniho vyvoje nekdo zanesl do kodu chybku a za pomerne vzacnych podminek je treba nejaky vystup lehce jiny - treba se jedno cislo zmenilo o 10% (u nas v praxi nastane treba to, ze z 5000 testu je ve 3 docela prehlednutelna zmena). Jak zajistite, aby to nasel tester rucne na konci toho rocniho vyvoje? Jak pak zjistite kde se chyba stala? Z me zkusenosti by realita byla takova, ze si toho proste nikdo nevsimne a v blazene nevedomosti se aplikace vypusti do sveta. Pokud mate aplikaci, ktera nema textove/numericke/graficke vystupy, pak ok, vase situace je jina.
Nerikam ze je nekdo blbec, pokusim se vysvetlit jak jsem to myslel. My kdyz jsme testy nemeli, tak jsme byli presne v takove situaci jakou popisujete - dlouhy vyvoj, na konci se to poradne rucne otestovalo, vypadalo to dobre, tak to slo ven. Az zakaznici zjistovali, ze se jim od minule verze zmenily vystupy. Kdybysme proste jen udelali hromadu testu a pousteli je jako nahradu za ty manualni na konci vyvoje, tak by nam to opravdu nic neprineslo a sam bych si myslel, ze to delame blbe. Museli jsme zmenit cely postup vyvoje a ano, stalo to hodne penez a taky nejaky cas trvalo, nez to zacalo nest ovoce. Ovsem ziskali jsme tim duveru zakazniku a zridka se nam stane, ze neco utece ven.
Férovější by bylo srovnávat (automatické) jednotkové testy a automatické integrační testy a netahat do toho „bandu testerů“, která bude dělat manuální testy (což samozřejmě vyjde* draho).
Jednotkové testy jsou v první řadě pomůcka pro vývojáře a – můžou zlepšovat týmovou práci, usnadňují refaktoring vnitřků metod/tříd, dodávají takový ten pocit jistoty a jiné výhody. Ale s kvalitou softwaru z pohledu zákazníka (tzn. jak SW plní požadavky) nemají společného prakticky nic.
*) je otázka, po kolika iteracích/verzích se to projeví, ale asi se shodneme na tom, že je lepší to mít naskriptované, než s každou verzí ručně klikat nebo psát příkazy. Manuální testování bude vycházet lépe jen ve výjimečných případech (když se dělá jen jedna verze nebo když jsou zásadní změny a pak jde o prakticky jiný produkt nebo když to z nějakých objektivních příčin nejde zautomatizovat atd.).
> Otestovat všechno pomocí TTD spotřebuje násobky času nutného ke tvorbě aplikace
dokaž to
> Proto to mnoho softwarových společností řeší přes service packy, kdy se jednoduše zjištěné chyby řeší až v provozu, až na opravdu velké výjimky.
každej software obsahuje chyby a TDD na tom nic nezmění, můžeš používat TDD i vydávat aktualizace, to si nijak neprotiřečí
ale k důkladně otestovanýmu software zřejmě budeš vydávat těch aktualizací míň; netvrdim nic o tom že se to musí nutně vyplatit
Obavam se ze se pletete. Mozna si neuvedomujete, ze pri testovani "cele aplikace" se samozrejme testuji hlavne komponenty ze kterych je ta aplikace slozena, a pak komponenty ktere pouzivaji tyto komponenty, atd.
Tj. pokud je jakykoliv program napsan alespon trochu kulturne (tj. mala provazanost modulu/trid, minimalizace vedlejsich efektu), je testovani velmi snadne, protoze se testuje vzdy jen jeden (vice ci mene) celistvy "modul A".
Pokud testy potvrdi ze funguje spravne, v "modulech" ve vyssi vrstve, ktere "modul A" pouzivaji, se jiz NETESTUJE funkcionalita "modulu A", takze realna komplexita testu je stale velmi nizka (coz si myslim ze je dost zasadni) bez ohledu na to jak moc "vysoko" nebo "nizko"-urovnovy testovany modul je.
Takze nevidim ZADNY duvod, proc by mel byt problem testovat zrovna ucetnictvi Pohoda.
To jsou teoretické řeči zcela odtržené od reality.
Ve většině reálných aplikací je nutno prakticky na každé úrovni testovat prakticky všechny vlastnosti úrovně i podúrovní, protože programátoři nejsou stroje ale lidé a ti dělají chyby a dokážou doku*vit i prosté předání dat do a z nižší úrovně nebo do jiného modulu. Takže funkcionalita jiných modulů může být nakrásně bezchybná, ale ve vyšší úrovni se objevují nepochopitelné chyby. Tím se dostáváme k tomu, že složitost testů je pak následně nereálně vysoká, tudíž se nedělají.
Napsal jsem nize,
https://www.youtube.com/watch?v=x8jdx-lf2Dw
Odtrzene od reality jsou spis vase reci. Dam jen priklad - kod >10M radku, radove tisice UT, kolem 10k integracnich testu. Jen spusteni aplikace, otevreni projektu a nasledne ladeni v debuggeru trva asi minutu. UT je napsany za par minut, ladit se muze hned, takze ve vysledku je TDD mnohem rychlejsi nez bez testu a rekl bych ze cim vetsi aplikace, tim rychlejsi je vyvoj pres UT.
Uprimne, uz dlouho jsem neslysel nazory podobne vasemu. Jeste pred par lety jsme to novacky ucili, ted uz s tim maji zkusenost temer vsichni a chapou jejich prinos.
Taky jsem se nedávno rozepsal k testům, i když spíš na téma 'proč', než 'jak':
http://www.tomas-dvorak.cz/clanky/k-cemu-dohaje-nejaky-junit-testy
trochu mi to pripomina komunismus. Ten by taky fungoval, kdyby byli vsichni uvedomeli. Ale ono nejsou :-).
A podobne je to s temi testy. Vetsina programatoru neni uvedomelych. Ale treba by se to dalo udelat jako za socialismu. Deti tech programatoru, kteri nepisi testy, se treba nedostanou na stredni skolu a pujdou delat do kotelny.
Srovnání s komunismem je dost nešťastné.
Použití jednotkových testů je dobrá praktika, která vývoj zefektivňuje. Takže pokud je tým, který se o efektivitu vývoje stará, pak ji zavede. Já to zažil, máme teď méně regresí, nebojíme se refaktorovat, což má další benefity. Zkrátka jsme se domluvili, že nový kód bude mít testy a pokud nemá, tak se to řeší při peer review (ne všechno testovat lze, to je jasné).
Pokud je tým složený z neumětelů, tak je to ztracené.
Článek tu na rootu je ubohý. Ale ten blogpost na který reaguješ je dobrý a s ním souhlasím.
Samozrejme,
takhle se daji psat testy ale nikdo rozumny to tak delat nebude.
Pouzivani assertu by se dalo popsat jako je unit testovani 1. generace. Vetsina vyvojaru je nekde uprostred 2. generace. Proc ale psat o 1 generaci kdyz nastupuje 3. generace ktera prinasi obrovsky skok.
Článek má za úkol motivovat programátory, aby ty testy psali. Použil jsem co nejjednodušší nástroje, aby bylo patrné, proč se to dělá. Zahltit začátečníka pravidly (de facto dalším programovacím jazykem) pro používání knihovny JUnit je jeden z jednoduchých způsobů, jak se nechat poslat do /dev/null.
Článků na JUnit je dostatek. Nechtěl jsem nosit dříví do lesa.
Myslim ze, okrem ineho, autor zabudol spomenut vyznamy prinos TDD. Jeho spravnou aplikaciou sa v nie malej miere zvysuje citatelnost a nasledne testovatelnost kodu test teamom. Zabuda sa totizto, ze pre testing je dolezita vlastnost testovatelnosti aplikacie, pripadne jej komponentov
Je to seriál nebo samostatný článek?
Pokud to druhé, hodnotím jako zbytečnost s plýtvání časem čtenářů, ostatně jako většina článků o testování.
U obhajoby/propagaci testování není třeba ukázat jak, ale přínos. A ten na podobném triviálním testu prokázat nelze. Napište např. primitivní blog nad J2EE metodou TDD a ukažte mi tím, jakou část kódu dokážete smysluplně pokrýt. Úmyslně vybírám takové téma, kde není téměř žádná business logika.
Ahoj, koukám názorů je spousta, ale nikde nevidím nikoho křičet, že TDD a testování softwaru jednotkovýma testama neni jedno a to samé. S odvoláním např na R.C.Martina či Kenta Becka a jim podobných, není TDD vůbec o testování chyb (to je druhořadé), ale především o kvalitním objektovém návrhu ! Skutečnost, že mám pár (nebo klidně všechny) tříd pokrytých testama, neznamená, že praktikuju TDD.
To nic nemění na tom, že TDD je výborná koncepce vývoje software a všem doporučuju knihu http://www.growing-object-oriented-software.com/. Umět pracovat s JUnit taky neznamená umět vyvíjet software pomocí TDD.
Rozumných a hodnotných článků či seriálů o opravdovém vývoji řízeném testy bych se s trochou nadsázky dopočítal na prstech jedné ruky.
kouknu na to, dik za tip
ja to myslel spiš obecně, že je članek chycenej za špatnej konec, než jako že bych chtěl rozebirat samotny TDD. co se mě tyče (zatim sem to video nevidel) tak mě nenapada duvod proč by to mělo vest k proceduralnimu programovani. to asi dost zaleži na tom kdo to TDD aplikuje a jak přemyšli. Pokud žiješ v objektovym světě tak nenapišeš test tak aby vyustil v nějakou směs procedur...zitra zkouknu a třeba změnim nazor :-)
Asert neni vhodny k unit testovani a neni na nej ani urceny - pouziva se tam, kde cgci mit test rovnou v ostrem kodu a zapnout si ho tam treba pri debuggingu (napr. proto, ze v runtime je test prilis drahy, treba kontrola setrideni seznamu na vstupu, ktere je pozadovano jako kontrakt metody a ma ho delat volajici). Pokud nechci pouzivat JUnit, tak bych si stejne napsal vlastni pomocnou tridu s metodami ala assertEquals, assertEmpty, assertNull atd., cimz by se staly testy citelnymi a vyhnul bych se zacatecnickym chybam typu porovnani double hodnot pomoci == (existuje vlastne jeste neco jako redaktor?). Podobne nazvy trid zacinajici malymi pismeny, nazvy lokalnich promennych shodne s member, coz je sice "jen" styl, ale i tak hruza.
Doufam ze je to cele vtip, protoze tuto perlu z diskuse snad autor nemuze myslet vazne:
Není to produkční třída, ale testovací. Tu je možné napsat jakkoli, na kvalitu kódu se nehledí.
ja si ze zajmem prectu podobne clanky a u toho testovani si rikam, jake to delaji lide vlastne to software.
Ja pouzivam napr. mnozstvi cizich modulu z CPANu , C-funkce davam k dispozici pro intrepretry pres swig a pouzivam radu dalsich knihoven a tools. Zadny ten software nema nejake jednotkove testy a v tech tools je schovano urcite 80% vseho, co zakaznik dostane. To bych mel okolo toho vseho psat ty unit-testy?
Jak to delaji ty 'spravne' firmy, ktere to vsechno porad dokola testuji. Pisou uplne vsechno samy?