Property-based testing (PBT) je moderní přístup k testování softwaru, který převrací klasické psaní testů naruby. Místo toho, abys vymýšlel konkrétní vstupy (např. "co se stane, když zadám číslo 5"), definuješ vlastnosti (properties), které by měl tvůj kód splňovat pro jakýkoliv platný vstup.
Knihovna Hypothesis je pro Python v tomto směru naprostým standardem a špičkou v oboru.
V běžném testu (např. v pytest) píšeš tzv. example-based testy:
- Vstup: 2 a 3.
- Očekávaný výsledek: Součet je 5.
V property-based testu pomocí Hypothesis:
-
Vstup: Jakákoliv dvě celá čísla (
$x, y$ ). -
Vlastnost: Součet
$x + y$ musí být stejný jako$y + x$ (komutativita).
Hypothesis za tebe generuje stovky náhodných testovacích případů, které odpovídají tvé definici dat. Pokud najde chybu, provede tzv. shrinking (zmenšování). To znamená, že se snaží najít nejjednodušší možný příklad, který chybu stále vyvolává (např. místo obrovského seznamu s tisíci prvky ti ukáže, že kód padá už při seznamu s jedním prvkem [0]).
Představ si, že máš funkci, která má seřadit seznam čísel.
from hypothesis import given, strategies as st
def sort_numbers(numbers):
# Představme si, že tady je naše implementace
return sorted(numbers)
@given(st.lists(st.integers()))
def test_sort_numbers_properties(numbers):
result = sort_numbers(numbers)
# Vlastnost 1: Výsledek má stejnou délku jako vstup
assert len(result) == len(numbers)
# Vlastnost 2: Prvky v seznamu jsou seřazeny (každý je menší nebo roven následujícímu)
for i in range(len(result) - 1):
assert result[i] <= result[i+1]
# Vlastnost 3: Výsledek obsahuje stejné prvky jako originál
assert sorted(result) == sorted(numbers)@given(...): Dekorátor, který říká Hypothesis, co má generovat.st.lists(st.integers()): Strategie, která říká: „Vytvoř seznamy náhodných celých čísel libovolné délky.“- Hypothesis tento test spustí typicky 100x s různými bizarními hodnotami (prázdný seznam, záporná čísla, extrémně velká čísla).
- Najde "Edge Cases": Člověk často zapomene otestovat prázdný řetězec, nulu nebo speciální znaky. Hypothesis na ně nezapomene nikdy.
- Shrinking: Když test selže, Hypothesis ti nevyhodí jen chybu, ale ten nejmenší možný vstup, který ji způsobil. To drasticky zrychluje ladění.
- Dokumentace vlastností: Nutí tě přemýšlet o tom, co tvůj kód skutečně garantuje, nejen jaké dává výsledky pro pár čísel.
Není nutné psát PBT pro všechno. Nejvíce zazáří u:
- Algoritmů (řazení, vyhledávání, transformace dat).
- Parsování a serializace (např. JSON -> objekt -> JSON by se nemělo změnit).
- Integrace a API, kde očekáváš určitý formát dat.
Máš nějaký konkrétní kód nebo funkci, u které přemýšlíš, jak ji otestovat pomocí vlastností?