18. května 2008

Komentovat? Určitě ano.

Opět jsem se setkal s názorem, že komentovat zdrojové kódy není potřeba, že kód sám o sobě je dokumentace. K tomu můžu říci jen jedno - to je naprostá blbost.

Stačí nepracovat s vlastním kódem několik týdnů a už člověk ztrácí přehled o jemných detailech algoritmů, které sám psal. Nemluvě pak o tom, když je potřeba opravit chybu v rok staré aplikaci a nebo pracovat v kódu svých kolegů.

Také jsem slyšel "Jsem orientovaný na výkon a psaní komentářů mě brzdí". To je hodně krátkozraké, protože možná je člověk o pár minut rychlejší, když implementuje algoritmus, ale z dlouhodobějšího pohledu je to samozřejmě krátkozraké - čas strávený nad zjišťováním, jak jsem to já nebo můj kolega vlastně tehdy mysleli, je mnohem větší než kolik se dá ušetřit na jednom algoritmu bez komentářů. Ale já bych se vůbec do těchto polemik nepouštěl, protože dle mého názoru zdrojový kód se automaticky rovná kód plus komentáře.

Při psaní komentářů je potřeba nezapomínat, že zdrojové kódy nejsou Java soubory, ale také třeba konfigurační soubory, soubory prezentační vrstvy atd. To jsou také zdrojáky a ty je potřeba také komentovat.

Opačný extrém je takový, že na jeden řádek kódu připadají dva řádky komentáře. Není potřeba komentovat to, co je zřejmé z vlastního kódu. Zdrojový kód je jako dobrodružná knížka, kde jazyk Java popisuje vlastní děj příběhu. Komentáře jsou pak dějová vysvětlení, aby se čtenář v jednotlivých zápletkách neztratil. Pokud je toho vysvětlování příliš na úkor vlastního děje, tak pak to asi moc záživná knížka nebude.

14. května 2008

Máte čas na unit testy?

Pokud bych si měl hned sám odpovědět, tak dle mého názoru moc času není. Není z jednoho hlavního důvodu a to jsou peníze resp. náklady plynoucí z času, který bude věnován psaní unit testů. Hned na začátku také musím dodat, že celý článek je o "normálních" jednorázových projektech, které nejsou nějak mission-critical. U vývoje produktu (tj. aplikace, kterou zabalím a pošlu zákazníkům nebo aplikace, kterou opakovaně dodávám) předpokládám, že bude prostor pro psaní testů mnohem větší.

Ještě jsem nedělal ve firmě, kde by se počítalo s tím, že N dní budu vyvíjet produkční kód a dalších N dní budu mít vyhrazeno na testování (pozn. píši to sice v pořadí produkční kód, testy, ale klidně je možné si představit přístup opačný - TDD). Takto to často prezentují agilní přístupy k vývoji softwaru, ale v praxi je dle mého názoru toto neuskutečnitelné, aspoň tedy v rámci projektového vývoje, protože poměr nákladů na psaní unit testů vs. přínosy z toho plynoucí nejsou zrovna moc pozitivní.

V žádném případě nejsem odpůrce psaní testů, ale realita mě nějak naučila se na tu problematiku dívat i z jiného pohledu než jen vývojářského. Vidím spoustu výhod ze psaní testů, zejména následující dva:

  • zajištění požadované kvality produkčního kódu
  • kvalitou se nemyslí jen kód bez chyb, ale i takové věci, jako kvalitní architektura aplikace, dobrá dekompozice problému apod. Pokud chci psát efektivně testy, tak pak potřebuji mít i dostatečně kvalitní produkční kód.

Samozřejmě bez testů to nejde, nedovedu si představit, že bych takto odevzdal aplikaci zákazníkovi. Ale na jaké testy se zaměřit, aby přínosy a náklady byly v rozumné rovnováze? Dle mých zkušeností jsem asi nejlepší poměr přínosy vs. náklady zaznamenal v těchto případech:
  • znovupoužitelný kus kódu (knihovna, modul)
  • stěžejní aplikační logika, např. jádro aplikace
  • doménové objekty - equals. Na to jsou již testy napsané, takže je jen použít. Přínos možná malý, ale ušetří spoustu času při hledání chyb s kolekcemi.
  • při použití ORM nástroje testovat základní CRUD operace nad objekty. Pro tyto účely jsem si napsal sérii testů, protože je to stejné pořád dokola a je dobré vědět, že práce s DB na té základní úrovni funguje jak má. Spíše je to testování ORM mapování jako celku, než jen samotného procesu ukládání dat do DB.

Naopak mám negativní zkušenost z Mock (jMock, EasyMock) testů servisních a jiných interních rozhraní v aplikaci. Přínosem určitě bylo to, že mi testy drží strukturu aplikace pohromadě, ale velkou nevýhodou byla ztráta flexibility - kdykoliv jsem provedl nějaký refaktoring, tak jsem musel měnit i tyto testy. Testy se musí měnit vždy s ohledem na změny produkčního kódu, ale v oblasti rozhraní se mění a přidává celkem hodně a dle mého názoru výhody nepřevažují nevýhody.

Speciální kapitolou je testování GUI. Již jsem se na toto téma jednou rozepsal, kde jsem porovnával nástroje pro unit testy GUI. Bohužel je dost často rychlejší tedy levnější nechat GUI testy provést manuálně, než testy vytvořit a testovat automaticky. Většina si hned asi v duchu řekne, že je to možná levnější během vývoje, ale z pohledu nasazení, údržby a podpory aplikace to už neplatí. Toto je asi pravda, ale těžko se to prosazuje v průběhu vývoje. Úplně nejlepší je zapojit do testování zákazníka. Snažíme se vyvíjet iteračním způsobem a vždy na konci každé iterace dáme hotovou část aplikace zákazníkovi, který to následně připomínkuje.

Mě by hodně zajímalo, zda můj pohled na věc odráží realitu současného vývoje aplikací nebo zda jsem mimo. Znám spoustu firem resp. kolegů, kteří ještě nenapsali ani čárku testovacího kódu, ale na druhé straně znám i firmy, kde se na testování klade velký důraz. Já bych sám rád testoval určitě více než doposud, ale ekonomické tlaky od obchodníků, projekt managerů a vedoucích mi to moc nedovolují.