Pokrytí kódu Pythonu
Python je jedním z nejoblíbenějších programovacích jazyků současnosti. Díky své univerzální povaze nachází Python uplatnění v různých případech použití při vývoji softwaru, od jednoduchého skriptování přes webové servery až po frameworky jako Django.
Stejně jako u jiných programovacích jazyků však i v Pythonu zůstává testování jedním z nejdůležitějších aspektů vývoje softwaru.
V tomto příspěvku se seznámíme s několika nástroji pro měření a zápis pokrytí kódu Pythonu testovacími případy.
Unittest
Standardní knihovna Pythonu je předpřipravena s modulem unittest. Unittest je testovací framework inspirovaný JUnitem a dalšími frameworky pro jednotkové testování z hlavních programovacích jazyků, který umožňuje automatizovat testy, nastavit sdílené nastavení a vypnutí kódu pro testy a další.
Jednou z důležitých funkcí unittestu je test fixture, tj. nastavení potřebné pro spuštění jednoho nebo více testů, a všechny související úklidové akce. Pomocí textového fixture lze činnosti, jako je vytváření dočasných nebo zástupných databází, adresářů nebo spuštění serverového procesu, vyřídit na jednom místě.
Vezměme si několik ukázkových testů a podívejme se, jak se implementují pomocí unittestu:
import unittest
třída TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual(‚foo‘.upper(), ‚FOO‘)
def test_isupper(self):
self.assertTrue(‚FOO‘.isupper())
self.assertFalse(‚Foo‘.isupper())
def test_split(self):
s = ‚hello world‘
self.assertEqual(s.split(), )
# ověříme, že s.split selže, když oddělovač není řetězec
s self.assertRaises(TypeError):
s.split(2)
if __name__ == ‚__main__‘:
unittest.main()
Vytvořte testovací případ podtřídou unittest.TestCase. Pak můžete definovat jednotlivé testy pomocí metod. Všimněte si, že názvy testovacích případů by měly začínat slovem test. Tato konvence pojmenování informuje test runner o tom, které metody představují testy.
Test runner je komponenta, která organizuje provádění testů a poskytuje výsledek uživateli. Jeho implementace se liší a může používat grafické rozhraní, textové rozhraní nebo vracet speciální hodnotu, která indikuje výsledky provedení testů.
Pytest
Pytest je testovací framework Pythonu třetí strany. Jeho cílem je poskytnout rámec pro efektivní psaní testů tím, že odstraní všechny režijní náklady na vytváření testů. Pytest je podporován jazyky Python 2.7, 3.4, 3.5, 3.6, Jython, PyPy-2.3 v systémech Unix/Posix a Windows.
Podívejme se, jak s Pytestem začít.Nejprve si stáhněte nejnovější verzi a nainstalujte ji pomocí pip:
Nainstalovanou verzi můžete zkontrolovat pomocí:
Nyní si vezmeme ukázkovou funkci a související testovací případ.
def func(x):
return x + 1def test_answer():
assert func(3) == 5
Funkce func přijímá vstup x a vrací hodnotu x + 1.
Funkce test_answer(3) == 5. V testovacím případě assertujeme, zda funkce func přijme vstup 3 a vrátí 5. Očekává se, že tento testovací případ selže. Pro spuštění testu stačí zadat příkaz pytest do adresáře, ve kterém je soubor test_sample.py.
$ pytest
=========================== test session starts ============================
platform linux – Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 itemtest_sample.py F ================================= FAILURES =================================
_______________________________ test_answer ________________________________
def test_answer():
> assert func(3) == 5
E assert 4 == 5
E + kde 4 = func(3)
test_sample.py:5: AssertionError
========================= 1 failed in 0.12 seconds =========================
Coverage.py
Coverage.py je jedním z nejpopulárnějších nástrojů pro pokrytí kódu v jazyce Python. K měření pokrytí využívá nástroje pro analýzu kódu a sledovací háčky poskytované ve standardní knihovně jazyka Python. Funguje na hlavních verzích systémů CPython, PyPy, Jython a IronPython. Coverage.py můžete používat s unittestem i Pytestem.
Můžete si buď stáhnout nejnovější verzi Coverage a nainstalovat ji ručně, nebo ji můžete nainstalovat pomocí pip as:
Nyní spusťte svůj program pomocí coverage as
Dále pro získání dat pokrytí proveďte
Tady je ukázka výstupu dat pokrytí
Name Stmts Miss Cover Missing
——————-
my_program.py 20 4 80% 33-35, 39
my_other_module.py 56 6 89% 17-23
——————-
TOTAL 76 10 87%
Vygenerujte report v html souboru:
$ coverage html
Toto je ukázkový HTML report vygenerovaný programem Coverage.py. Obsahuje Modul, příkazy, chybějící, vyloučené, větve, částečné a pokrytí.
Pytest-cov
Pytest-cov je zásuvný modul Pythonu pro generování reportů pokrytí. Kromě funkcí podporovaných příkazem coverage podporuje také centralizované a distribuované testování. Podporuje také pokrytí podprocesů.
Pokud jste napsali testovací případy podle požadavků Pytestu, můžete použít Pytest-cov ke spuštění všech testů a vykázání pokrytí.
Chcete-li začít, nainstalujte Pytest-cov takto:
Centralizované testování
Centralizované testování vykazuje kombinované pokrytí hlavního procesu a všech jeho podprocesů. Centralizované testování můžete spustit pomocí,
Distribuované testování
Instalace Pytest-xdist, pro podporu distribuovaných systémů:
Distribuované testování lze provádět ve dvou režimech, dist nastavit na load a each. Při nastavení na load se při distribuovaném testování hlásí kombinované pokrytí všech podřízených zařízení. Podřízené servery mohou být rozloženy na libovolný počet hostitelů a každý podřízený servery může být umístěn kdekoli v souborovém systému. U každého podřízeného serveru budou měřeny jeho dílčí procesy.
Při distribuovaném testování v každém režimu pytest-cov také vykazuje kombinované pokrytí všech podřízených serverů. Protože na každém slave běží všechny testy, umožňuje to generovat kombinovaný report pokrytí pro více prostředí
Shrnutí
V tomto příspěvku jsme se seznámili s různými frameworky pro jednotkové testování a pokrytí kódu v jazyce Python. I když tyto rámce usnadňují proces testování, stále je třeba psát testy. Zde je několik osvědčených postupů, které je třeba při psaní jednotkových testů zvážit.
- Používejte dlouhé, popisné názvy. Tím často odpadá potřeba doktrín v testovacích metodách.
- Testy by měly být izolované. Nepřicházejte do styku se skutečnou databází nebo sítí. Používejte oddělenou testovací databázi, která se strhne, nebo používejte makety objektů.
- Soustřeďte se na jeden malý kousek funkčnosti.
- Měly by být rychlé, ale pomalý test je lepší než žádný test.
- Často má smysl mít jednu třídu testovacích případů pro jednu třídu nebo model.
Využívejte testovací případy pro jednu třídu nebo model.