Typový system versus unittesty

Kit

Re:Typový system versus unittesty
« Odpověď #375 kdy: 25. 06. 2018, 22:29:24 »
Nejprve spustím test, ten spustí kompilaci jednotky a otestuje ji. Test tedy spouštím při překladu nebo ne?
Ne. Testy se spouští při buildu. Build a compile není to samé.

To bych se načekal. Někdy spouštím testy i 3× za minutu.


Re:Typový system versus unittesty
« Odpověď #376 kdy: 25. 06. 2018, 23:00:56 »
Nejprve spustím test, ten spustí kompilaci jednotky a otestuje ji. Test tedy spouštím při překladu nebo ne?
Ne. Testy se spouští při buildu. Build a compile není to samé.

To bych se načekal. Někdy spouštím testy i 3× za minutu.
Podle me nepoustis testy, ale aparatus. Aparatus zajisti, ze se prelozi "jednotka" (pricemz probehne typova kontrola) pak se prelozi test a nakonec se test spusti. Takze unit test se spusti (tesne) po prekladu, ale rozhodne ne pri nem.

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Typový system versus unittesty
« Odpověď #377 kdy: 25. 06. 2018, 23:11:35 »
Nejprve spustím test, ten spustí kompilaci jednotky a otestuje ji. Test tedy spouštím při překladu nebo ne?
Ne. Testy se spouští při buildu. Build a compile není to samé.

To bych se načekal. Někdy spouštím testy i 3× za minutu.

No a?

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Typový system versus unittesty
« Odpověď #378 kdy: 25. 06. 2018, 23:12:49 »
Nejprve spustím test, ten spustí kompilaci jednotky a otestuje ji. Test tedy spouštím při překladu nebo ne?
Ne. Testy se spouští při buildu. Build a compile není to samé.

To bych se načekal. Někdy spouštím testy i 3× za minutu.
Podle me nepoustis testy, ale aparatus. Aparatus zajisti, ze se prelozi "jednotka" (pricemz probehne typova kontrola) pak se prelozi test a nakonec se test spusti. Takze unit test se spusti (tesne) po prekladu, ale rozhodne ne pri nem.
Sleduj. Teď zase odskočí někam jinam.

Kit

Re:Typový system versus unittesty
« Odpověď #379 kdy: 25. 06. 2018, 23:14:50 »
To bych se načekal. Někdy spouštím testy i 3× za minutu.
Podle me nepoustis testy, ale aparatus. Aparatus zajisti, ze se prelozi "jednotka" (pricemz probehne typova kontrola) pak se prelozi test a nakonec se test spusti. Takze unit test se spusti (tesne) po prekladu, ale rozhodne ne pri nem.

Konečně to někdo pochopil :)

Jednotkové testy už prostě používám jako druhou fázi kompilace.


BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Typový system versus unittesty
« Odpověď #380 kdy: 25. 06. 2018, 23:26:21 »
To bych se načekal. Někdy spouštím testy i 3× za minutu.
Podle me nepoustis testy, ale aparatus. Aparatus zajisti, ze se prelozi "jednotka" (pricemz probehne typova kontrola) pak se prelozi test a nakonec se test spusti. Takze unit test se spusti (tesne) po prekladu, ale rozhodne ne pri nem.

Konečně to někdo pochopil :)

Jednotkové testy už prostě používám jako druhou fázi kompilace.
Až na to, že to kompilace není, protože nic nekompiluješ. No nic, log-off.

.

Re:Typový system versus unittesty
« Odpověď #381 kdy: 25. 06. 2018, 23:33:46 »
Nemám sílu to už sledovat, takže se omlouvám, pokud něco opakuji.

Osobně vidím rozdíl mezi unittestem a kontrolu pomocí typového systémem tak, jak je zde popsán. Zatímco typový systém určuje omezení, kterým podléhá výsledek, unit test specifikuje vstupy a pro něj správný výstup. Rozumím tomu, že typový popis vypadá velmi elegantně a zachycuje všechny možné hodnoty. Ale nastavit správný typ pro komplexní funkce nemusí být triviální a může se v něm zrcadlit algoritmus výpočtu, což může snadno zanést chybu. Naproti tomu unit test, jakkoliv zachytí jen velmi omezenou množinu možných hodnot, je triviální - vstupy a požadovaný výstup. Možnost chyby velmi omezená. A proto se budou typový systém a unit testy, IMHO, vždy doplňovat. Čím dokonalejší typový systém, tím může být unit tetsů méně, ale nemyslím si, že je možné je zcela pominout. Chyba může vzniknout nejen při programování funkce, ale i při definici typu.

Kit

Re:Typový system versus unittesty
« Odpověď #382 kdy: 25. 06. 2018, 23:39:57 »
Až na to, že to kompilace není, protože nic nekompiluješ. No nic, log-off.

V PHP je sice kompilace skryta, ale interpretr to už dávno není. A tato kompilace se spouští až po spuštění testů.

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Typový system versus unittesty
« Odpověď #383 kdy: 25. 06. 2018, 23:52:34 »
Nemám sílu to už sledovat, takže se omlouvám, pokud něco opakuji.

Osobně vidím rozdíl mezi unittestem a kontrolu pomocí typového systémem tak, jak je zde popsán. Zatímco typový systém určuje omezení, kterým podléhá výsledek, unit test specifikuje vstupy a pro něj správný výstup. Rozumím tomu, že typový popis vypadá velmi elegantně a zachycuje všechny možné hodnoty. Ale nastavit správný typ pro komplexní funkce nemusí být triviální a může se v něm zrcadlit algoritmus výpočtu, což může snadno zanést chybu. Naproti tomu unit test, jakkoliv zachytí jen velmi omezenou množinu možných hodnot, je triviální - vstupy a požadovaný výstup. Možnost chyby velmi omezená. A proto se budou typový systém a unit testy, IMHO, vždy doplňovat. Čím dokonalejší typový systém, tím může být unit tetsů méně, ale nemyslím si, že je možné je zcela pominout. Chyba může vzniknout nejen při programování funkce, ale i při definici typu.
Rozumím. Ale chyba může vzniknout i při psaní testu. Vzhledem k tomu, jak často zoufale nečitelné mohou testy být - velmi snadno.

Jednou se mi stalo, že jsem našel chybu v kódu, který měl stoprocentní pokrytí testy. Byl to den, kdy jsem na coverage zanevřel.

Kit

Re:Typový system versus unittesty
« Odpověď #384 kdy: 25. 06. 2018, 23:57:55 »
Rozumím. Ale chyba může vzniknout i při psaní testu. Vzhledem k tomu, jak často zoufale nečitelné mohou testy být - velmi snadno.

Jednou se mi stalo, že jsem našel chybu v kódu, který měl stoprocentní pokrytí testy. Byl to den, kdy jsem na coverage zanevřel.

Dnes i testy musí mít stejnou úroveň jako produkční kód. Pokud jsou nečitelné, tak to autorovi dřív nebo později někdo omlátí o hlavu. Pokud jsi našel chybu v kódu, tak zcela jistě neměl 100% pokrytí testy.

andy

Re:Typový system versus unittesty
« Odpověď #385 kdy: 26. 06. 2018, 01:19:54 »
Pokud jsi našel chybu v kódu, tak zcela jistě neměl 100% pokrytí testy.
ale no tak... test může být prostě blbě - buď je chyba v něčem, co nekontroluje (např. testuje, že delete smaže prvek, ale nezkontroluje, že nesmaže víc než je požadováno) - 100% pokrytí splněno. Nebo máš testy, kdy se testuje, že pro zadaný vstup to dává furt stejný výstup...až na to, že ten "stejný" výstup je od začátku blbě. Opět klidně 100% pokrytí..

Re:Typový system versus unittesty
« Odpověď #386 kdy: 26. 06. 2018, 07:29:46 »
Rozumím. Ale chyba může vzniknout i při psaní testu. Vzhledem k tomu, jak často zoufale nečitelné mohou testy být - velmi snadno.
To je ovšem dané špatným způsobem psaní testů. Jednotkové testy mají testovat, zda pro „zajímavé“ vstupy dává kód očekávané výstupy. Není důvod, proč by takový test měl být nečitelný. V testu samozřejmě může být chyba, ale pak se na ní obvykle přijde při spouštění testů, protože test neprojde. Vzhledem k tomu, že je test napsaný úplně jiným způsobem, než testovaný kód, je velmi nepravděpodobné, že by v něm byla stejná algoritmická chyba (zejména když v testu žádný algoritmus nemá být). Samozřejmě je možné, že tam bude systematická chyba – test bude očekávat chybný výstup, protože programátor špatně pochopil zadání. Jenže pokud programátor špatně pochopil zadání, bude chyba v kódu vždy, i když bude mít sebelepší typový systém nebo jakýkoli jiný systém kontroly. Tam je jediná šance, že ten test bude psát někdo jiný, kdo zadání pochopí jinak – ale ani to není stoprocentní cesta k úspěchu, protože problém bývá velmi často v tom zadání, takže je dost pravděpodobné, že ho dva programátoři pochopí stejně špatně. A konečně zřejmě nejčastější důvod, proč test neodhalí chybu, je ten, že nepokrývá všechny zajímavé případy – takže chyba bude jednoduše v něčem, co se netestuje. 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.

Jednou se mi stalo, že jsem našel chybu v kódu, který měl stoprocentní pokrytí testy. Byl to den, kdy jsem na coverage zanevřel.
Vy se neustále míjíte s podstatou problémů. Stoprocentní pokrytí kódu testy znamená, že se při testech projdou všechny „řádky“ (ve skutečnosti instrukce) programu. To samozřejmě v žádném případě neznamená, že jsou otestované všechny případy. Pokrytí kódu testy se používá opačně – když nemáte stoprocentní pokrytí kódu testy, máte takřka jistotu, že nepokrytý kód není otestován žádným způsobem. (Zbývá malá možnost, že nepokrytý kód je nedostupný, pak by ale stejně v kódu neměl být.) Takže pokud jste chybu v kódu, který měl stoprocentní pokrytí testy, našel jenom jednou, zažil jste toho zatím opravdu málo. Že jste na code coverage zanevřel po nalezení jediné chyby svědčí pouze a jen o nedostatku pokory, a to vás pak nezachrání sebelepší nástroje. Proto jsem vám už minule psal, že nemáte hledat stříbrnou kulku, která nějak mechanicky zajistí, že budete psát bezchybné programy (to je nemožné), a radši byste se měl snažit pochopit, k čemu slouží nástroje, které máte k dispozici, a správně je používat. Pak můžete dobrý kód psát i v Javě, v JavaScriptu nebo PHP.

Kit

Re:Typový system versus unittesty
« Odpověď #387 kdy: 26. 06. 2018, 08:31:52 »
Pokud jsi našel chybu v kódu, tak zcela jistě neměl 100% pokrytí testy.
ale no tak... test může být prostě blbě - buď je chyba v něčem, co nekontroluje (např. testuje, že delete smaže prvek, ale nezkontroluje, že nesmaže víc než je požadováno) - 100% pokrytí splněno. Nebo máš testy, kdy se testuje, že pro zadaný vstup to dává furt stejný výstup...až na to, že ten "stejný" výstup je od začátku blbě. Opět klidně 100% pokrytí..

To je jen formálně 100% pokrytí, které spočítají nějaké automatické vyhodnocovače. To bych mohl napsat prázdné testy, které by nic nedělaly a také tvrdit, že mám 100% pokrytí. Ostatně totéž se běžně dělá i u typů, protože se s tím nikdo nechce piplat.

andy

Re:Typový system versus unittesty
« Odpověď #388 kdy: 26. 06. 2018, 08:34:38 »
Vzhledem k tomu, že je test napsaný úplně jiným způsobem, než testovaný kód, je velmi nepravděpodobné, že by v něm byla stejná algoritmická chyba (zejména když v testu žádný algoritmus nemá být).
Až na to, že pokud algoritmus něco složitého "počítá", tak není moc šance na to psát unit test buď tak, že ten algoritmus implementuje někdo jiný/jinak, nebo tak, že se prostě výsledek algoritmu vezme jako že je "správně". Ono to má své opodstatěnění, při refaktoringu/optimalizaci to najde, co to rozbilo (nebo naopak spravilo), ale bohužel chyby to často moc nemá šanci najít.
Citace
A konečně zřejmě nejčastější důvod, proč test neodhalí chybu, je ten, že nepokrývá všechny zajímavé případy – takže chyba bude jednoduše v něčem, co se netestuje. 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.
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.

Takže čistě z praktického hlediska u této konkrétní kategorie chyby bude typický výsledek ten, že typované programy prostě nullpointerexception vyhazovat nebudou, netypované "testované" ano, protože to programátor zapomněl na spoustě míst ošetřit a testy to nenašly.

Já to spíš vidím tak, že některé věci prostě není praktické psát do typů (navíc  u některých věcí neexistuje třeba jazyk, který by tyhle věci byl schopen vůbec vyjádřit, u souladu se specifikací to IMO u spousty věcí fakt nejde), někdy by z toho i tak bylo víc práce než užitku.... (na druhou stranu, prakticky kdykoliv jsem nepoužil NonEmpty pro neprázdný list, tak se mi to vymstilo).

Ale konkrétně - jak jsem se inspiroval tím LLVM paperem, tak jsem napsal interpret na ten Mapbox style jazyk a běželo to bez testů napoprvé (po cca. 5 hodinách psaní) a doteď jsem v tom kódu interpretu žádnou chybu nenašel (měl jsem jednu chybu mimo interpret, kdy jsem ve 3 ráno omylem napsal && místo ||). A tady je mimo jiné odpověď na týkající se otázky na "méně kódu" - díky těm typům pak při interpretaci není potřeba kontrolovat, jakého typu jsou vstupy funkcí. Protože prostě mají ten správný typ.

andy

Re:Typový system versus unittesty
« Odpověď #389 kdy: 26. 06. 2018, 08:35:30 »
Pokud jsi našel chybu v kódu, tak zcela jistě neměl 100% pokrytí testy.
ale no tak... test může být prostě blbě - buď je chyba v něčem, co nekontroluje (např. testuje, že delete smaže prvek, ale nezkontroluje, že nesmaže víc než je požadováno) - 100% pokrytí splněno. Nebo máš testy, kdy se testuje, že pro zadaný vstup to dává furt stejný výstup...až na to, že ten "stejný" výstup je od začátku blbě. Opět klidně 100% pokrytí..

To je jen formálně 100% pokrytí, které spočítají nějaké automatické vyhodnocovače. To bych mohl napsat prázdné testy, které by nic nedělaly a také tvrdit, že mám 100% pokrytí. Ostatně totéž se běžně dělá i u typů, protože se s tím nikdo nechce piplat.
Chápu správně, že tvá definice "100% pokrytí" == "kód pracuje správně"?