Jenže ideální by bylo se obejít zcela bez testů a správnost programu dokázat. To z mnoha důvodů většinou nejde. Proto se snažíme dokázat (rozhodnout na základě statické analýzy zdrojových textů, pro všechny možné vstupy a bez nutnosti program spouštět) aspoň něco. Statická typová analýza je jedním z nástrojů, jak dokázat aspoň některé vlastnosti programu. Jestliže nějaké tvrzení o programu dokážeme (v matematickém slova smyslu), tak si můžeme být jistí, že platí.
Také by mohlo být ideální obejít se bez statických typů. Bude to znamenat pouze určitou ztrátu výkonu, což v dnešní době není považováno za podstatné. Statická analýza může být (a také bývá) součástí testů.
Kupodivu i v dnešní době na výkonu často záleží. Jaký je rozdíl, když je statická analýza (nejspíš včetně typové analýzy, pokud k ní kód poskytuje dostatek informací) součástí testů a ne kompilátoru? Kromě toho, že je pak potřeba statickou analýzu v testech vůbec řešit a kompilátor tyto informace nemůže použít pro optimalizaci?
Potreba vykonu je jen v nekterych prápadech. Proto se arduino bude programt v C asi vzdy a webove stranky asi nikdy. Dnes je vykonu tolik, ze mnohem vyznamnejsi je produktivita, ktera je vyssi u flexibilnejsich dynamickych jazyku. Staticke analyza u testu ma vyhodu v tom, ze ji lze pouzit jen tam kde je vhodna a potrebna. Idealni univerzalni jazyk budoucnosti by tedy mel mit moznost statickych typu, ale nepovinne. K necemu takovemu ma nakroceno cython, ktery kombinuje vyhody dynamickych a statickych jazyku.
Na druhou stranu testy většinou žádné obecné tvrzení o programu nedokazují, protože je není možné napsat tak, aby pokryly úplně celý stavový prostor programu. Takže se spoléháme na to, že otestujeme některé speciální situace, v lepším případě zvolené "chytře", např. na základě znalosti kódu, v horším případě vybrané náhodně, v nejhorším případě vybrané systematicky špatně. Když testy neohlásí chybu, tak věříme, že je program dobře. Ale ve skutečnosti jsme jen ověřili, že nenastane chyba pro určitou (většinou malou) podmnožinu vstupů. A to ještě za předpokladu, že nějaká chyba v testu nezamaskuje přítomnost chyby v kódu.
Zpravidla testujeme pouze okrajové podmínky, kdy program má fungovat a kdy naopak musí vyhodit výjimku. Na znalost kódu se spoléhat nemůžeme, protože ho v době psaní testů ještě nemáme. Když testy neohlásí chybu, tak zpřesníme testy, to je základ. Nevěř testům, které projdou.
Testy není nutné psát dřív než kód. U některých je to dost nevhodné. Kdybych bral poslední dvě věty doslova, tak nevím, jak poznám, že je program připraven pro produkční nasazení.
Mne prijde, ze je tu malo programatoru z praxe, programatoru, kteri vytvari skutecny produkcni kod, ktery neco poradneho dela, vydelava penize a za to jsou ti programatori placeni. Vypada to, ze je to tu samy teoreticky programator, ktery ma nastudovanu teorii typu, ale nikdy zadny realny produkt nevytvoril. Testovat se musi nejen ze program funguje a dela to co ma, ale i to, ze selze a nedela to co nema. Vetsinou se od programu nechce aby fungoval za kazdou cenu, ale hlavne aby nenadelal skody. Pokud zakaznik predem doda testy, je to to nejlepsi co muze programatora potkat, protoze programator zpravidla nerozumi byznysu a procesum zakaznika a aplikaci z funkcniho hlediska otestovat neumi. Programator vi, ze nemuze scitat int se stringem, ale to ani zdaleka nestaci. Ono se treba take musi otestovat, ze zkratovaci souprava muze byt osazena jen na jedno miste a na jednom miste muze byt jen jedna zkratovaci souorava s vyjimkou nekolika mist, ze musi byt osazena na prikaz b a nejde ji sundat, dokud plati, ale muze zustat osazena i po jeho ukonceni, ze muze byt osazena na vice prikazu b, ze jeden prikaz muze byt prilohou jineho prikazu b, kdy se pozadavky prenasi, ze jsou prikazy b ciste na odjisteni, kdy se nezajistuje, ze existuje moznost docasneho odjisteni na prikaz b a rada dalsich pravidel, ktere zakaznik upresnuje zpravidla az kdyz je aplikace hotova a poukazuje na chyby v aplikaci a divi se, ze to programatori nevi a udelali spatne, protoze je to prece vsechno jasne a logicke. Teda s tim, ze na ruznych lokalitach bezi procesy trochu odlisne, coz je potreba take zohlednit, coz ani zakaznik sam netusil, protoze pozadavek zadava nejaky manager, kterynti sam do detailý nezna. Ale rozhodne to nesmi byt spatne, protoze kdyz to bude fungovat spatne, pujde elektrikarum o zivot. No a to se bavime o velmi jednoduche evidencni knize, ktera se da naprogramovat za par dnu, ale otestovat ji dukladne a pustit do provozu je zalezitost na nekolik mesicu. Kazda uprava a zasah do kodu vyzaduje provest testy na vsechny vazby a podminky znovu, aby se overilo, ze se nic nenarusilo. Kod testu je rozsahlejsi nez sama aplikace. A staticke typy v tom hraji zcela marginalni ulohu. Aplikace musi byt v C#, protoze takove je zakaznikovo prostredi a rozumne nic jineho nepripusti, aby to byl schopen rozumne udrzovat. Takova je realna praxe, panove. A pak tady jsou s prominutim imbecilove, kteri zcela vazne tvrdi, ze kdyz aplikace projde kompilatorem, tak je v podstate hotovo.
Když mám k dispozici dva kontrolní mechanismy, které jsou do značné míry komplementární, tak se mi nezdá vhodné jeden z nich zahodit (a ještě ten s principiálně silnější vypovídací schopností) a tvářit se, že jsem zachoval stejnou úroveň kontroly.
Proto se tyto kontrolní mechanismy kombinují. Smalltalk šel cestou testování a možná proto se tolik nerozšířil. Haskell se vydal cestou statického typování, ale bez testů se také neobejde. Nejlépe jsou dnes na tom jazyky, které oba přístupy volně kombinují. Proto byly do PHP či Pythonu přidány volitelné statické typy a proto se staticky typované programy nejen dokazují, ale i testují.
Právě že se programy nedokazují, a proto se musí testovat. I staticky typované jazyky kombinují oba přístupy. Já jsem nebyl ten, kdo prosazoval, že nejsou potřeba statické typy, protože testy. A netvrdím ani to, že statická typová analýza je náhradou testů.
Staticke typy mohou pomoci pri overovani spravnosti kodu, ale jsou zbytne, nezbytne jsou testy. Staticke typy v tomto smeru hraji druhe housle.