2011-11-02 11 views
7

Estoy tratando de escribir pruebas unitarias para asegurar la corrección de varios decoradores que he escrito. Aquí está el comienzo del código que estoy tratando de escribir:¿Cómo probar los decoradores de función 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() 

Aunque esto funciona bastante bien para la estrategia MRU tengo arriba, planeo escribir estrategias adicionales, en cuyo caso tendrá que decorar con el función fib de diferentes maneras. (Recuerde que debido a que fib llama a fib, configurar fib2 = memoize (fib) no memoriza los valores intermedios para que no funcionen.) ¿Cuál es la forma correcta de probar los otros decoradores?

Respuesta

8

Tome un vistazo a las pruebas en la biblioteca estándar de ejemplos: http://hg.python.org/cpython/file/3.2/Lib/test/test_functools.py#l553

Yo suelo añadir algunos instrumentación a la función que se envuelve para que pueda controlar las llamadas.

En lugar de memorizar la función de prueba en el nivel de módulo, creo la función memorada dentro de la prueba para que se cree una nueva para cada prueba y para cada variante de decorador.

+0

Ah, claro. No estoy seguro de por qué no pasó por mi mente el no usar nada más que los números de Fibonacci. –

+0

Me gustaría ver su código MRU cuando haya terminado. Con suerte, publicará un enlace. –

+0

¡Claro! El código para mi memoizer está aquí: https://github.com/Casar/memoizer EDITAR: Creo que mi mru.py en realidad debería llamarse lru.py –

1

¿Y el más complicado

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

De esta manera se podría hacer

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 muy inteligente! –

Cuestiones relacionadas