*********
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:

.. code-block:: python

    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``.
