2011-11-02 18 views
7

Sto provando a scrivere test unitari per garantire la correttezza dei vari decoratori che ho scritto. Ecco l'inizio del codice che sto cercando di scrivere:Come testare i decoratori di funzioni Python?

import unittest 

from memoizer import Memoizer 
from strategies.mru import MRU 


@Memoizer(strategy=MRU(maxsize=10)) 
def fib(x): 
    if x < 2: 
    return 1 
    else: 
    return fib(x-1) + fib(x-2) 


class TestMemoizer(unittest.TestCase): 

    def test_simple(self): 
    self.assertEqual(fib(0), 1) 
    self.assertEqual(fib(1), 1) 
    self.assertEqual(fib(10), 89) 


if __name__ == '__main__': 
    unittest.main() 

Anche se questo funziona decentemente per la strategia MRU che ho sopra, ho intenzione di scrivere ulteriori strategie, nel qual caso avrò bisogno di decorare con la funzione fib in diversi modi. (Ricorda che poiché fib chiama fib, l'impostazione fib2 = memoize (fib) non memorizza i valori intermedi in modo che non funzioni.) Qual è il modo corretto di testare gli altri decoratori?

risposta

8

Date un'occhiata ai test nella libreria standard per gli esempi: http://hg.python.org/cpython/file/3.2/Lib/test/test_functools.py#l553

Io di solito aggiungere un po ' strumentazione alla funzione che è stata spostata in modo da poter monitorare le chiamate.

Invece di memoizzare la funzione di test a livello di modulo, creo la funzione memoized all'interno del test in modo che ne venga creata una nuova per ciascun test e per ogni variante di decoratore.

+0

Ah, giusto. Non sono sicuro del motivo per cui non mi è venuto in mente di non usare nulla quindi i numeri di Fibonacci. –

+0

Sarei interessato a vedere il codice MRU quando hai finito. Spero che pubblichi un link. –

+0

Sicuro! Il codice per il mio memoizer è qui: https://github.com/Ceasar/memoizer EDIT: Penso che il mio mru.py dovrebbe in realtà essere chiamato lru.py –

1

Che dire del piuttosto complicato

def mkfib(strategy): 
    @Memoizer(strategy=strategy) 
    def fib(x): 
     if x < 2: 
     return 1 
     else: 
     return fib(x-1) + fib(x-2) 
    return fib 

In questo modo si potrebbe fare

fib1 = mkfib(MRU(maxsize=10)) 
self.assertEqual(fib1(0), 1) 
self.assertEqual(fib1(1), 1) 

fib2 = mkfib(MRU(maxsize=10)) # produces another cache 
self.assertEqual(fib2(0), 1) 
self.assertEqual(fib2(1), 1) 
+0

Idea molto intelligente! –

Problemi correlati