Testování

Různé přístupy k testům:

pozitivní testy (testy splněním, test-to-pass)
Provádějí verifikaci konkrétního chování za očekávaných podmínek. Cílem je ověřit správnou funkčnost při běžném používání.
negativní testy (testy selháním, test-to-fail)
Ověřují chování v abnormálních/neočekávaných podmínkách. Cílem je ověřit, že aplikace vhodně zareaguje. Typicky ověřují „alternativní toky v kódu“.

Oba typy testů píšeme tak, aby prošly - v negativních zachytáváme očekávanou výjimku/chybovou hlášku apod. Tyto typy pak vhodně kombinujeme - typicky jeden nebo více pozitivních testů a několik negativních testů.

Úrovně testování

Testy dělíme podle rozsahu testovaného kódu:

Jednotkové
Testy nejmenších částí systému - třídy, metody, funkce.
Integrační
Testování, že podsystémy (moduly) fungují správně dohromady.
Systémové
Obsáhlé testovací scénáře, které procházejí celým systémem.
Akceptační
Testy při převzetí zákazníkem, scénáře předem domluvené oběma stranami.

Rozdělení podle toho, co je testováno

Funkční testy
Testuje jednotlivé funkce z pohledu uživatele - vychází z funkčních požadavků.
Zátěžové testy
Testuje chování systému pod zátěží, tedy například zda „ustojí“ očekávané množství uživatelů.
Bezpečnostní testy
Název snad mluví za vše. :-)

Anatomie testu

Testovací případ má typicky 3 fáze: ARRANGE - ACT - ASSERT

  1. ARRANGE: Nastavení počátečních podmínek testu - vytvoření objektů, se kterými se bude pracovat, příprava dat, …
  2. ACT:Provedení požadované akce.
  3. ASSERT: Ověření správnosti výstupu.

Příklad:

def test_sum():
    # 1. Arrange:
    test_data = [1, 2, 3, 4, 5]
    # 2. Act:
    result = sum(test_data)
    # 3. Assert:
    assert 15 == result

Pokrytí kódu

Pokrytí kódu (Cove Coverage): počet elementů pokrytých testy / celkový počet elementů [%]

Různé druhy:

Line/Statement Coverage
Množina řádek, které byly v průběhu testů vykonány. Tyto řádky kódu jsou tak pravděpodobně správné - pokud máme správné testy pokrývající dostatečné množství případů.
Branch Coverage
Pokrytí každé větve podmínky - včetně přeskočení podmínky, která nemá větev else.
Condition Coverage
Pokrytí každé části výrazu v podmínce.
Path Coverage
Pokrytí všech možných cest kódem.

Ilustrativní příklad - vizte p04_testing.intro.

pytest

Nástroj pro automatické testování, oproti unittest přímo v Pythonu je jednodušší na začátek a snáze se s jeho pomocí píší testy – není potřeba dědit třídy, stačí pouze příkaz assert.

Předpokládá určité konvence v pojmenování:

  • Soubory obsahující testy se jmenují test_*.py, nebo *_test.py.
  • Každý testovací případ je reprezentován funkcí/metodou s prefixem test_. V případě metody musí název třídy začínat na Test.