En general, quiero desactivar el menor código posible, y quiero que sea explícito: no quiero que el código que se está probando decida si es una prueba o no, quiero que la prueba diga que el código "hey" Por cierto, estoy ejecutando una prueba de unidad, ¿pueden hacer su llamada a Solr? En su lugar, pueden poner lo que enviarían a Solr en este lugar para que pueda verificarlo ". Tengo mis ideas, pero no me gustan. Espero que haya una buena manera pitónica de hacerlo.En Python, ¿cuál es un buen patrón para deshabilitar cierto código durante las pruebas unitarias?
Respuesta
Uso Michael Foord de Mock en su unidad de prueba a hacer esto:
from mock import Mock
class Person(object):
def __init__(self, name):
super(Person, self).__init__()
self.name = name
def say(self, str):
print "%s says \"%s\"" % (self.name, str)
...
#In your unit test....
#create the class as normal
person = Person("Bob")
#now mock all of person's methods/attributes
person = Mock(spec=person)
#talkto is some function you are testing
talkTo(person)
#make sure the Person class's say method was called
self.assertTrue(person.say.called, "Person wasn't asked to talk")
#make sure the person said "Hello"
args = ("Hello")
keywargs = {}
self.assertEquals(person.say.call_args, (args, keywargs), "Person did not say hello")
Tienes dos maneras de hacer esto es sin , o mínima en el caso de DI, modificaciones a su código fuente
La forma cleanest es usando dependency injection, pero I don't reallylike extensive monkeypatching, y hay algunas cosas que son imposibles/difíciles de hacer eso dependency injection hace que sea fácil.
Puede usar Mock objects para interceptar las llamadas a métodos que no desea ejecutar. P. ej. Tiene alguna clase A
, donde no desea llamar al método no()
durante una prueba.
class A:
def do(self):
print('do')
def no(self):
print('no')
Un objeto de burla podría heredar de A
y anular no()
no hacer nada.
class MockA(A):
def no(self):
pass
A continuación, crear MockA
objetos en lugar de A
s en su código de prueba. Otra forma de burlarse sería tener A
y MockA
implementando una interfaz común, digamos InterfaceA
.
Hay toneladas de marcos burlones disponibles. Ver StackOverflow: Python mocking frameworks.
En particular, ver: Google's Python mocking framework.
La creación de subclase para implementar la burla trae potencialmente todo tipo de cosas que no necesita. Además, sus métodos no toman el primer argumento requerido –
Wow, realmente estoy cavando Mock de Michael Foord. Es hermoso lo fácil que es crear objetos simulados en Python. Si ha tenido que hacer esto manualmente en C++ utilizando la interfaz y la herencia, sabrá cuán doloroso podría ser esto. EDITAR: Por cierto, esta respuesta realmente no es correcta para Mock, pero señala el camino hacia lo que podrías estar buscando. Ver [http://www.voidspace.org.uk/python/mock/examples.html#creating-a-mock-from-an-existing-object] – manifest
@Mike Graham, gracias por señalar el argumento que falta. No digo que la subclasificación sea la mejor manera de burlarse, solo estaba dando un ejemplo. –
Normalmente, cuando ocurre algo como esto, usa Monkey Patching (también llamado Duck Punching) para lograr los resultados deseados. Consulte this link para obtener más información sobre Monkey Patching.
En este caso, por ejemplo, sobrescribiría solr para simplemente imprimir la salida que está buscando.
Sé que es el caso de uso típico para los objetos de imitación, pero eso es también una vieja discusión ... son objetos necesarios Mock en absoluto o ¿son evil?
Estoy del lado de aquellos que creen que los simulacros son evil y tratarían de evitar cambiar el código probado en absoluto. Incluso creo que tal necesidad de modificar el código probado es un olor a código ...
Si desea cambiar o interceptar una llamada de función interna para fines de prueba, también podría hacer de esta función una dependencia externa explícita configurada en instanciation time que sería proporcionada tanto por su código de producción como por código de prueba. Si lo haces, el problema desaparecerá y terminarás con una interfaz más limpia.
Tenga en cuenta que al hacerlo no es necesario cambiar el código probado ni internamente ni mediante la prueba que se realiza.
El gran problema que tuve fue con la mecánica de la inyección de dependencia. Ahora me di cuenta de esa parte.
Necesito importar el módulo exactamente de la misma manera en ambos lugares para insertar con éxito el nuevo código. Por ejemplo, si tengo el siguiente código que desee desactivar:
from foo_service.foo import solr
solr.add(spam)
Me parece que no puede hacer esto en el corredor de prueba en mi:
from foo import solr
solr = mock_object
el intérprete de Python debe ser el tratamiento de los módulos foo_service.foo
y foo
como entradas diferentes. Cambié from foo import solr
al más explícito from foo_service.foo import solr
y mi objeto simulado fue inyectado con éxito.
- 1. ¿Cómo deshabilitar las traducciones durante las pruebas unitarias en django?
- 2. ¿Cuál es un buen patrón para escribir pruebas unitarias dentro de un cuaderno de Mathematica?
- 3. ¿El código duplicado es más tolerable en las pruebas unitarias?
- 4. Pruebas unitarias en Python
- 5. Pruebas unitarias para acceder al código ActiveDirectory
- 6. Deshabilitar generadores de pruebas unitarias en Rails
- 7. Pruebas unitarias Arquitectura de patrón de visitante
- 8. Desactivación de ciertos aspectos durante las ejecuciones de pruebas unitarias
- 9. Pruebas unitarias Código AS3 para Flash
- 10. ¿Hay algún buen marco de pruebas unitarias para Ada?
- 11. Pruebas unitarias para malloc()
- 12. ¿Garantiza la cobertura del código en las pruebas unitarias?
- 13. IDLE para ejecutar pruebas unitarias Python PyUnit
- 14. ¿Qué pruebas con las pruebas unitarias?
- 15. Pruebas unitarias para las bibliotecas núcleo jQuery
- 16. ¿Es malo agregar código solo para pruebas unitarias?
- 17. Python - Pruebas torcidas y unitarias
- 18. marcos de las pruebas unitarias para C
- 19. Interfaces de pruebas unitarias en Python
- 20. Pruebas unitarias en C++
- 21. ¿Estás ejecutando un código durante cierto tiempo en C#?
- 22. ¿Es posible ignorar ciertas pruebas unitarias?
- 23. Pruebas unitarias Fallas WCF
- 24. ¿Existe un buen patrón para reutilizar las consultas de Morphia?
- 25. Jerarquía de archivos adecuada para pruebas unitarias en Python
- 26. ¿Cómo se separan las pruebas unitarias de las pruebas de integración en Visual Studio?
- 27. Cuándo usar las pruebas unitarias?
- 28. Pruebas unitarias de generación automática para el código Java heredado
- 29. Pruebas unitarias para impresión en Java Swing
- 30. Pruebas unitarias para excepciones en el constructor Python
¡Guau, simulacro es increíble! Gracias. En mis días de C++/Java solía pasar demasiado tiempo escribiendo clases simuladas a mano. – guidoism
Sí, no es broma! Acabo de enterarme de esto leyendo esta pregunta. Definitivamente lo agregué al libro de trucos – manifest
Desde Python 3.3, hay un módulo 'unittest.mock' [en la biblioteca estándar] (https://docs.python.org/ 3/library/unittest.mock.html) –