Modul doctest - Testování dokumentačních řetězců

17. 9. 2008 19:58 (aktualizováno) Tomáš Ehrlich

Nedávno jsem poprvné commitoval rozšíření pro Django (a pro FOSS obecně). Bylo mi řečeno, že musím doplnit dokumentaci a testy. To mě přivedlo k tomuto modulu a proto jsem se rozhodl, že ho víc prozkoumám (pozn: prozkoumám == prolítnu okem dokumentaci a zjistím, jak ho používat mimo Django ;) ).

Modul doctest nabízí snadnou cestu pro vytváření jednoduchých testů. Název sice uvadí, že se jedná o testování dokumentačních řetězců, mužeme ale místo toho použít externí soubor a oddělit tak vlastní kód od testů. Osobně bych nesnesl, kdybych měl v jednom souboru kód, kompletní dokumentaci a ještě k tomu testy.

Příklad na úvod:

"""
The example module supplies one function, factorial().  For example,

>>> factorial(5)
120
"""

def factorial(n):
    """Return the factorial of n, an exact integer >= 0.
    >>> [factorial(n) for n in range(6)]
    [1, 1, 2, 6, 24, 120]
    >>> [factorial(long(n)) for n in range(6)]
    [1, 1, 2, 6, 24, 120]
    >>> factorial(30)
    265252859812191058636308480000000L
    >>> factorial(30L)
    265252859812191058636308480000000L
    >>> factorial(-1)
    Traceback (most recent call last):
        ...
    ValueError: n must be >= 0

    Factorials of floats are OK, but the float must be an exact integer:
    >>> factorial(30.1)
    Traceback (most recent call last):
        ...
    ValueError: n must be exact integer
    >>> factorial(30.0)
    265252859812191058636308480000000L
    """

    import math
    if not n >= 0:
        raise ValueError("n must be >= 0")
    if math.floor(n) != n:
        raise ValueError("n must be exact integer")
    result = 1
    factor = 2
    while factor <= n:
        result *= factor
        factor += 1
    return result

def _test():
    import doctest
    doctest.testmod()

if __name__ == "__main__":
    _test()

Pozn: Je to jen osekaný příklad z Pythoní dokumentace.

Pokud je zřejmé, jak skript funguje, můžete přeskočit na další nadpis.

doctest.testmain() Prohledá aktuální modul a ve všech dokumentačních řetězcích hledá řádky, které začínají jako prompt Pythoního interpretu, tedy „>>>“. Příkazy za tímto promptem spustí a jako výstup očekává hodnotu, která je uvedena na dalším řádku. Pokud skript neprojde, doctest vyhodí vyjímku.

Úspěšný test může ale také končit vyjímkou, např. faktoriál záporného čísla. Tuto vyjímku lze zapsat zkrácenou formou (pokud její obsah není k testování důležitý):

Traceback (most recent call last):
...
ValueError: n must be >= 0

Kde první řádek je hlavička Tracebacku, poslední je chybová hláška, kterou nám Python vyhodí. Tělo Tracebacku je ignorováno.

Spouštění testů

Metoda doctest.
  • testmod()
  • testfile(filename)

V obou případech Python mlčí, pokud všech testy proběhnou bez chyby. V případě, že chceme vědět, co děla, přidáme volbu -v(erbose) do parametru.

Skrytí testů

Pokud chceme nějaký test ukrýt před doctestem, stačí za příkaz přidat komentář  #doctest: +SKIP.

A to je zatím vše, co používám :)

Sdílet