Čtení kódu pokrytí

Tento příspěvek není příspěvek, který říká, že musíte mít procentuální pokrytí mezi X a Y v celé vaší kódové základně.
Je to úvodní příspěvek k pokrytí kódu, jak jej číst a jak jej můžete použít ve svém pracovním postupu.

Pokrytí kódu

Pokrytí kódu vám říká, který kód byl během testu spuštěn a kolikrát. Neříkám, abyste cílili na X procent pokrytí, protože to zcela závisí na tom, co vytváříte. Cílení na 100% pokrytí kódem je často chybou, protože to zabere spoustu času (dostat se tam a udržovat) a může to vést k problematickým testovacím postupům. Vysoké procento pokrytí nutně nezvyšuje kvalitu, chyby se vždy objeví.

Pokrytí kódu používám jako nástroj, jako poslední kontrolu k ověření, že je kód připraven. Dokáže objevit okrajové případy, na které jsme nepomysleli, a může zviditelnit špatně napsaný kód.

Jak na to

Můj aktuální rámec pro testování je Jest a tento rámec má vestavěné pokrytí kódu. Chcete-li vygenerovat pokrytí kódu vašeho projektu, můžete použít --collectCoverage vlajka.

jest --collectCoverage

Konfigurace Jest vám umožňuje nakonfigurovat některé parametry, jako je nastavení prahu, cesty k vyloučení z pokrytí a několik dalších.

Příklad

Pojďme to uvést do praxe. Jako test se podíváme na pokrytí kódem funkce fizz buzz.
FizzBuzz je malá funkce, která v závislosti na vstupu vrátí jiný výstup.
Pokud je vstupní hodnota:

  • je dělitelné třemi, vrací Fizz , např. 6
  • je dělitelné pěti, vrací Buzz , např. 20
  • je dělitelné třemi i pěti a vrací FizzBuzz , např. 15
  • jinak vrací vstupní hodnotu, např. 7

Možné řešení funkce fizz buzz vypadá následovně:

function fizzBuzz(value) {
  let output = ''
  if (value % 3 == 0) output += 'Fizz'
  if (value % 5 == 0) output += 'Buss'
  return output || value.toString()
}

Náš první test

Jako náš první test pokrýváme nejjednodušší případ, vstup, který není dělitelný a jednoduše vrací vstupní hodnotu:

describe('Returns the input', () => {
  it('if it is not divisible by three or five', () => {
    expect(fizzbuzz(7)).toBe('7')
  })
})

Pokud nyní vygenerujeme pokrytí kódem, uvidíme

Zpráva o pokrytí přímo v CLI:

Zpráva o pokrytí, kterou lze otevřít v prohlížeči (prostřednictvím ./coverage/lcov-report/index.html ):

Je dokonce možné kliknout na soubory, abyste viděli, které řádky jsou pokryty a které ne:

Na všech výše uvedených snímcích obrazovky máte čtyři různá procenta
podívat se.

Z Wikipedie:

  • Pokrytí příkazů – Byly provedeny všechny příkazy v programu?
  • Pokrytí větve – Byla provedena každá větev (nazývaná také DD-path) každé řídicí struktury (jako jsou příkazy if a case)? Například při zadaném příkazu if, byly provedeny větve true i false? Všimněte si, že toto je podmnožina pokrytí Edge.
  • Pokrytí funkcí – Byla volána každá funkce (nebo podprogram) v programu?
  • Byly provedeny všechny spustitelné řádky ve zdrojovém souboru pokrytí řádků?

Interpretace našeho pokrytí kódem

Z pokrytí si můžeme všimnout, že jsou pokryty všechny naše řádky, ale ne všechny výpisy. Přesněji řečeno, řádky, kde je vstupní hodnota dělitelná třemi a/nebo pěti.

Pokud bychom napsali testy tak, aby pokryly Fizz specifikace, vidíme, že nyní máme 100% pokrytí - huzza 🎉!.

describe('Fizz', () => {
  describe('Prints Fizz', () => {
    it('if it is divisible by three', () => {
      expect(fizzBuzz(3)).toBe('Fizz')
    })
  })

  describe('Does not print Fizz', () => {
    it('if it is not divisible by three', () => {
      expect(fizzBuzz(1)).not.toBe('Fizz')
    })

    it('if it is divisible by three and five', () => {
      expect(fizzBuzz(15)).not.toBe('Fizz')
    })
  })
})

Není divné, že nyní máme 100% pokrytí, zatímco nemáme správné testy na pokrytí Buzz a FizzBuzz výstup?
Je to proto, že v našem Fizz testy ověřují, že výstup vstupu 'nedělitelný třemi' a 'dělitelný třemi a pěti', oba nevedou k Fizz . Tímto způsobem se provádějí všechny naše příkazy, což má za následek 100% pokrytí kódem. To však neověřuje, že celý náš kód je správný. V tomto konkrétním případě by to nezachytilo chybně napsané Buzz (napsali jsme to jako Buss ) v našem programu, ale stále ukazuje 100% pokrytí.

Pokrytí kódu ve vašem pracovním postupu

Použití kódového pokrytí k ověření vašeho vlastního kódu nebo jako pomoc při kontrole kódu přináší kód do jiného světla. Pro mě, když vidím zvýrazněné řádky, často vyvolává několik otázek, na které jsem předtím nepomyslel. Jednou z těchto otázek je otázka, proč se nějaký kód nespustil, zvláště když si myslím, že by měl být vykonán.

Složité a neudržovatelné budou viditelné, protože budou zvýrazněny. Existují lepší nástroje pro sledování komplexních bloků kódu, ale dobrým ukazatelem může být prohlížeč pokrytí kódu.

Závěr

I když pokrytí kódem rozhodně má svou hodnotu, je snadné čísla špatně interpretovat. Poskytují důvěru při odesílání kódu a většinou povedou k aplikaci více testované v boji, ale neověřují, že byly splněny všechny obchodní požadavky ani nebyly správně implementovány .

Použití pokrytí kódem jako nástroje k ověření vašich myšlenek mě již několikrát zachránilo a zabránilo se odeslání neočekávaných chyb.
Složitý kód, nečitelný kód se objeví při pohledu na pokrytí kódem, protože bude mít pravděpodobně nízké procento. Možnou příčinou je zamotaný kód, známý jako kód špaget. Zde se budete muset rozhodnout kód přefaktorovat nebo jej nechat tak, jak je.