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.