Typový system versus unittesty

Kit

Re:Typový system versus unittesty
« Odpověď #405 kdy: 26. 06. 2018, 10:25:54 »
Pokud testy prochází a program přitom nepracuje správně, nemohu tvrdit, že má 100% pokrytí testy.
Ke slovesu pokrytí se váže předmět – tedy pokrytí čeho. Nemá smysl se tady dohadovat a neustále používat nevyjádřený předmět, když je zřejmé, že každý za předmět považuje něco jiného. Obvykle se „pokrytím testy“ myslí pokrytí kódu, tedy 100% pokrytí testy by znamenal pokrytí všech řádků/instrukcí. Které samozřejmě nezaručuje skoro nic, rozhodně nezaručuje bezchybnost. Vy asi myslíte 100% pokrytí všech možných případů, což je u jenom trošku větších věcí nedosažitelné.

Je to dosažitelné, pokud testované jednotky jsou dostatečně malé a jednoduché (SRP).


Re:Typový system versus unittesty
« Odpověď #406 kdy: 26. 06. 2018, 10:26:40 »
trochu offtopic, ale nemáte někdo nějakou teorii tohohle vehementního odmítání moderních technologií?
Nevšiml jsem si, že by tu někdo odmítal moderní technologie. Vidím tu jen nekritické přijímání něčeho, čemu dotyčný moc nerozumí, ale je to pro něj nové (ve skutečnosti to ale ani nic nového není), a má pocit, že to vyřeší všechny problémy světa. Na technologiích není důležité to, jestli jsou nové, ale jaké problémy umí (doopravdy) řešit.

andy

Re:Typový system versus unittesty
« Odpověď #407 kdy: 26. 06. 2018, 10:29:43 »
No... taková trapárna jako "null pointer exception". Problém je, že u silného typového systému člověk prostě dělá design tak, aby k té chybě vůbec nemohlo dojít už z principu. U testů je velmi jednoduché zapomenout testovat nějakou funkci na to, zda při nějaké konfiguraci vstupů nespadne na null pointer exception.
„Null pointer exception“ je řekl bych ukázkový příklad. Můžu to ošetřit pomocí typů, pomocí assertů a nebo to můžu testovat. BoneFlute tu asserty řadí do typového systému a dospěl k tomu tak, že začal do typů vkládat přímo testy. Asserty jsou přitom záměrně navržené tak, aby jednoduché případy mohl vyhodnocovat už kompilátor (nebo něco k němu přilepeného). Takže dohadovat se, co přesně je ještě součástí kompilace a co už ne je trochu akademická diskuse, protože to záleží na konkrétní implementaci – právě asserty se obvykle vyhodnocují až za běhu (poprvé tedy typicky v testech), ale stejně tak je může vyhodnocovat už kompilátor.
Typ Maybe fakt není assert.

Citace
Myslím, že je to opět spíš teoretický příklad. Z praktického hlediska bude k těm „null pointer exception“ docházet i v těch typových programech, protože ty nefungují ve vzduchoprázdnu, ale komunikují s okolím – a z něj ty NIL hodnoty dostávají. A i tam budou případy, kdy to programátor prostě přetypuje bez kontroly. Krásně je to vidět např. na Kotlinu, který nullable typy zavedl, ale když se někde váže na Javu, je to plné vykřičníků (tj. přetypování nullable typu na non-nullable, ze kterého může vypadnout NullPointerException).
Pokud programátor napíše "int x = (unsafeCoerce) 'string'", tak ho fakt nic nezachrání. Ale řekl bych, že je dost velký rozdíl mezi tímto a jazykem, kde člověk může napsat akorát "x = 'string' # comment: x je typu int".

v

Re:Typový system versus unittesty
« Odpověď #408 kdy: 26. 06. 2018, 10:31:12 »
Pokud testy prochází a program přitom nepracuje správně, nemohu tvrdit, že má 100% pokrytí testy.
Ke slovesu pokrytí se váže předmět – tedy pokrytí čeho. Nemá smysl se tady dohadovat a neustále používat nevyjádřený předmět, když je zřejmé, že každý za předmět považuje něco jiného. Obvykle se „pokrytím testy“ myslí pokrytí kódu, tedy 100% pokrytí testy by znamenal pokrytí všech řádků/instrukcí. Které samozřejmě nezaručuje skoro nic, rozhodně nezaručuje bezchybnost. Vy asi myslíte 100% pokrytí všech možných případů, což je u jenom trošku větších věcí nedosažitelné.

Je to dosažitelné, pokud testované jednotky jsou dostatečně malé a jednoduché (SRP).
jak by teda vypadaly testy pro 100% pokrytí tohoto kódu v pythonu:
Kód: [Vybrat]
def x(y, z): return y + z

Kit

Re:Typový system versus unittesty
« Odpověď #409 kdy: 26. 06. 2018, 10:32:23 »
Pokud testy prochází a program přitom nepracuje správně, nemohu tvrdit, že má 100% pokrytí testy.

100% pokrytí testy nelze dosáhnout ani teoreticky, protože Halting problem: https://en.wikipedia.org/wiki/Halting_problem

Doporučuju, Kite, nastudovat alespoň základy computer science, nebudeš se potom tady na fóru ztrapňovat tak často. A než začneš argumetovat tím, že je to jen teoretická konstrukce a nic takového, jako počítač s nekonečnou pamětí neexistuje, přečti si na wikipedii ten odstavec, který začíná The halting problem is theoretically decidable for linear bounded automata... a pochopíš, že to reálně opravdu udělat nejde.

Nikde jsem netvrdil, že 100% pokrytí testy lze dosáhnout. Stejně tak nelze 100 % funkcionality pokrýt typy.


andy

Re:Typový system versus unittesty
« Odpověď #410 kdy: 26. 06. 2018, 10:33:06 »
Pokud testy prochází a program přitom nepracuje správně, nemohu tvrdit, že má 100% pokrytí testy.
Ke slovesu pokrytí se váže předmět – tedy pokrytí čeho. Nemá smysl se tady dohadovat a neustále používat nevyjádřený předmět, když je zřejmé, že každý za předmět považuje něco jiného. Obvykle se „pokrytím testy“ myslí pokrytí kódu, tedy 100% pokrytí testy by znamenal pokrytí všech řádků/instrukcí. Které samozřejmě nezaručuje skoro nic, rozhodně nezaručuje bezchybnost. Vy asi myslíte 100% pokrytí všech možných případů, což je u jenom trošku větších věcí nedosažitelné.

Je to dosažitelné, pokud testované jednotky jsou dostatečně malé a jednoduché (SRP).
Tzn. mají na vstupu málo parametrů (které nejsou typově omezené....) a vevnitř málo podmínek a radši toho moc nevolají... Jinak řečeno pro nějaký normální program nedosažitelné.

netypová lopata

Re:Typový system versus unittesty
« Odpověď #411 kdy: 26. 06. 2018, 10:38:48 »
100% pokrytí testy nelze dosáhnout ani teoreticky, protože Halting problem: https://en.wikipedia.org/wiki/Halting_problem

Doporučuju, Kite, nastudovat alespoň základy computer science, nebudeš se potom tady na fóru ztrapňovat tak často. A než začneš argumetovat tím, že je to jen teoretická konstrukce a nic takového, jako počítač s nekonečnou pamětí neexistuje, přečti si na wikipedii ten odstavec, který začíná The halting problem is theoretically decidable for linear bounded automata... a pochopíš, že to reálně opravdu udělat nejde.

Nikde jsem netvrdil, že 100% pokrytí testy lze dosáhnout. Stejně tak nelze 100 % funkcionality pokrýt typy.

Jsi nějaký nekonzistentní, chlapče:
100% pokrytí všech možných případů, což je u jenom trošku větších věcí nedosažitelné.
Je to dosažitelné, pokud testované jednotky jsou dostatečně malé a jednoduché (SRP).

andy

Re:Typový system versus unittesty
« Odpověď #412 kdy: 26. 06. 2018, 10:42:15 »
No hlavně pokud 100% pokrytí nelze dosáhnout, tak je možné komukoliv, kdo tvrdí, že má 100% pokrytí říct, že prostě nemá... protože to přece nejde dosáhnout  :P

Re:Typový system versus unittesty
« Odpověď #413 kdy: 26. 06. 2018, 10:46:34 »
Typ Maybe fakt není assert.
Nic takového jsem nepsal. Napsal jsem, že „null pointer exception“ můžete řešit pomocí typů (mít typ, který NIL hodnotu nepřipustí), pomocí assertů (typ připouští NIL, ale na vstupu deklarujete pomocí assertu, že NIL je neplatná vstupní hodnota) a můžete to ošetřit testem (který NIL hodnotu pošle na vstupu a otestuje, zda se kód zachová očekávaným způsobem). To jsou různé způsoby zápisu kódu, a druhá věc je, co s tím pak dělá kompilátor. U typů je to nejjednodušší, tam se tak nějak očekává, že kompilátor tuto informaci použije. Ale kompilátor může použít i jiné informace, třeba z anotací nebo právě assertů – třeba IntelliJ Idea dělá analýzu kódu (je to obohacený kompilátor) a na základě toho odvozuje, zda se jedná o nullable nebo non-null typ. Takže ve zdrojovém kódu ten typ není uveden, při kompilaci se pomocí type inference odvodí, ale pak se dostane ke slovu type erasure a do zkompilovaného kódu se informace o typu opět nedostane (resp. je tam obecnější nullable typ).

Pokud programátor napíše "int x = (unsafeCoerce) 'string'", tak ho fakt nic nezachrání. Ale řekl bych, že je dost velký rozdíl mezi tímto a jazykem, kde člověk může napsat akorát "x = 'string' # comment: x je typu int".
Někdy v tom je velký rozdíl a někdy prakticky žádný. Existují různé problémy, takže i nástroje k jejich řešení jsou různé. Na něco se hodí programovací jazyk s bohatým typovým systémem, na něco typy vůbec nepotřebujete.

Kit

Re:Typový system versus unittesty
« Odpověď #414 kdy: 26. 06. 2018, 10:47:42 »
jak by teda vypadaly testy pro 100% pokrytí tohoto kódu v pythonu:
Kód: [Vybrat]
def x(y, z): return y + z

Stačí jeden test, který selže:
Kód: [Vybrat]
def testX(): assert(x("Ahoj", 42)=="Ahoj42")
Položil jsi otázku chybně. Nemáš funkci x. Zadáním pro test je: Napište funkci x, která sečte hodnoty parametrů. V tomto zadání však chybí specifikace parametrů. Co když na vstup někdo dá dva stringy nebo číslo a string? V posledně jmenovaném případu fuknce, kterou jsi nedůvodně napsal jako první, zahlásí chybu.


Re:Typový system versus unittesty
« Odpověď #415 kdy: 26. 06. 2018, 10:57:20 »
100% pokrytí (pozor na to že jsou dvě metriky - podle řádek a podle větví!) říká jen to, že všechen kód prošel alespoň jednou. Dává nám jistotu, že v kódu nejsou vyloženě dementní chyby typu překlepů, opačných podmínek, přehozených proměnných stejného typu, použití špatného typu (v případě jazyků bez typové kontroly při překladu) a podobně.

Unittesty rozhodně nezaručí (a v principu nemohou) správnou funkci pro všechny možné hodnoty daných typů, nebo dokonce všechny kombinace. To se dá zajistit typovým systémem, ale ne tím v mainstream jazycích :-)

TLDR: Unittest je nástroj sloužící především autorovi kódu k tomu, aby nebyl za debila.

v

Re:Typový system versus unittesty
« Odpověď #416 kdy: 26. 06. 2018, 11:02:00 »
trochu offtopic, ale nemáte někdo nějakou teorii tohohle vehementního odmítání moderních technologií?
Nevšiml jsem si, že by tu někdo odmítal moderní technologie. Vidím tu jen nekritické přijímání něčeho, čemu dotyčný moc nerozumí, ale je to pro něj nové (ve skutečnosti to ale ani nic nového není), a má pocit, že to vyřeší všechny problémy světa. Na technologiích není důležité to, jestli jsou nové, ale jaké problémy umí (doopravdy) řešit.
mj. jsem narážel na to vaše "sebelepší typový systém nemůže..."

v

Re:Typový system versus unittesty
« Odpověď #417 kdy: 26. 06. 2018, 11:11:07 »
jak by teda vypadaly testy pro 100% pokrytí tohoto kódu v pythonu:
Kód: [Vybrat]
def x(y, z): return y + z

Stačí jeden test, který selže:
Kód: [Vybrat]
def testX(): assert(x("Ahoj", 42)=="Ahoj42")
Položil jsi otázku chybně. Nemáš funkci x. Zadáním pro test je: Napište funkci x, která sečte hodnoty parametrů. V tomto zadání však chybí specifikace parametrů. Co když na vstup někdo dá dva stringy nebo číslo a string? V posledně jmenovaném případu fuknce, kterou jsi nedůvodně napsal jako první, zahlásí chybu.
děkuji za odpověď
předpokládejme tu vaši specifikaci ("sečte hodnoty parametrů") a zahoďme moji funkci, jak budou vypadat testy?

Phi

Re:Typový system versus unittesty
« Odpověď #418 kdy: 26. 06. 2018, 11:11:33 »
Kocouři, když se tu hádáte - jste si vědomi toho že "pokrytí" je dost vágní výraz a že se můžeme bavit jak o pokrytí usecasů tak o pokrytí kódu a u pokrytí kódů se zase můžeme, já nevím, snad o tuctu metrik, od function coverage přes branch coverage po statement coverage?
Halting problem se týká univerzálního algoritmu který by dokázal pro jakýkoliv program s jakýmkoliv vstupem rozhodnout, zda dokončí nebo nedokončí běh. Turing nikdy neřekl, že neexistuje algoritmus, který by pro konkrétní program nedokázal rozhodnout, zda dokončí či nedokončí. To je velký rozdíl.
100% coverage (kteréhokoliv druhů) samozřejmě možná je, jen je neskutečně drahá pro cokoliv co není triviální aplikace.

andy

Re:Typový system versus unittesty
« Odpověď #419 kdy: 26. 06. 2018, 11:15:41 »
Typ Maybe fakt není assert.
Nic takového jsem nepsal. Napsal jsem, že „null pointer exception“ můžete řešit pomocí typů (mít typ, který NIL hodnotu nepřipustí), pomocí assertů (typ připouští NIL, ale na vstupu deklarujete pomocí assertu, že NIL je neplatná vstupní hodnota) a můžete to ošetřit testem (který NIL hodnotu pošle na vstupu a otestuje, zda se kód zachová očekávaným způsobem). To jsou různé způsoby zápisu kódu, a druhá věc je, co s tím pak dělá kompilátor. U typů je to nejjednodušší, tam se tak nějak očekává, že kompilátor tuto informaci použije. Ale kompilátor může použít i jiné informace, třeba z anotací nebo právě assertů – třeba IntelliJ Idea dělá analýzu kódu (je to obohacený kompilátor) a na základě toho odvozuje, zda se jedná o nullable nebo non-null typ. Takže ve zdrojovém kódu ten typ není uveden, při kompilaci se pomocí type inference odvodí, ale pak se dostane ke slovu type erasure a do zkompilovaného kódu se informace o typu opět nedostane (resp. je tam obecnější nullable typ).
Musel jsem si dohledal, na co jsem reagoval a bylo to toto:
Citace
I tenhle typ chyby se bude objevovat u sebelepšího typového systému, protože když programátora nenapadne, že to je zajímavý případ a měl by na to udělat test, nenapadne ho ani ošetřit to v typovém systému.
Tak bych si dovolil tvrdit, že programátora v jazyce s ADT null pointer exception chybu řešit fakt napadne, protože tam jinak ten "null" nedostane, zatímco u assertu toho programátor fakt mnohokrát nenapadne tam ten assert vůbec dát. Takže konkrétně nullpointerexception mi připadá jako protipříklad Tvého tvrzení, a nepřipadá mi, že by cokoliv, co jsi napsal poté (byť třeba s tím odstavcem výše souhlasím) jakkoliv tu ideu, že typový systém a unit testy jsou srovnatelné, protože v obojím může udělat programátor chybu, podporovalo.