Si estoy escribiendo pruebas unitarias en python (usando el módulo unittest), ¿es posible generar datos de una prueba fallida, de modo que pueda examinarlos para ayudar a deducir qué causó el error? Soy consciente de la capacidad de crear un mensaje personalizado, que puede contener cierta información, pero a veces es posible que se trate de datos más complejos, que no se pueden representar fácilmente como una cadena.
Por ejemplo, suponga que tiene una clase Foo y está probando una barra de método, utilizando datos de una lista llamada testdata:
class TestBar(unittest.TestCase):
def runTest(self):
for t1, t2 in testdata:
f = Foo(t1)
self.assertEqual(f.bar(t2), 2)
Si la prueba falló, es posible que desee generar t1, t2 y / o f, para ver por qué estos datos en particular dieron como resultado una falla. Por salida, me refiero a que se puede acceder a las variables como cualquier otra variable, después de que se haya ejecutado la prueba.
fuente
msg
se usa, reemplazará el mensaje de error normal. Paramsg
que se agregue al mensaje de error normal, también debe configurar TestCase.longMessage en TrueTrue
.Usamos el módulo de registro para esto.
Por ejemplo:
Eso nos permite activar la depuración para pruebas específicas que sabemos que están fallando y para las que queremos información de depuración adicional.
Sin embargo, mi método preferido no es dedicar mucho tiempo a la depuración, sino dedicarlo a escribir pruebas más detalladas para exponer el problema.
fuente
foo
? ¿Una función separada? ¿Una función de método deSomeTest
? En el primer caso, una función puede tener su propio registrador. En el segundo caso, la otra función del método puede tener su propio registrador. ¿Conoce cómo funciona ellogging
paquete? Varios registradores son la norma.Puede utilizar declaraciones de impresión simples o cualquier otra forma de escribir en stdout. También puede invocar el depurador de Python en cualquier lugar de sus pruebas.
Si usa nose para ejecutar sus pruebas (que recomiendo), recopilará la salida estándar para cada prueba y solo se la mostrará si la prueba falló, por lo que no tiene que vivir con la salida desordenada cuando las pruebas pasan.
nose también tiene interruptores para mostrar automáticamente las variables mencionadas en afirmaciones, o para invocar al depurador en pruebas fallidas. Por ejemplo
-s
(--nocapture
) evita la captura de stdout.fuente
print
ylog.debug()
uno al lado del otro, y activo explícitamente elDEBUG
registro en la raíz desde elsetUp()
método, pero soloprint
aparece el resultado.nosetests -s
muestra el contenido de stdout si hay un error o no, algo que encuentro útil.No creo que esto sea exactamente lo que está buscando, no hay forma de mostrar valores de variables que no fallan, pero esto puede ayudarlo a acercarse a generar los resultados de la manera que desea.
Puede utilizar el objeto TestResult devuelto por TestRunner.run () para el análisis y procesamiento de resultados. En particular, TestResult.errors y TestResult.failures
Acerca del objeto TestResults:
http://docs.python.org/library/unittest.html#id3
Y algún código para apuntarle en la dirección correcta:
fuente
Otra opción: iniciar un depurador donde falla la prueba.
Intente ejecutar sus pruebas con Testoob (ejecutará su suite unittest sin cambios), y puede usar el interruptor de línea de comando '--debug' para abrir un depurador cuando una prueba falla.
Aquí hay una sesión de terminal en Windows:
fuente
El método que utilizo es realmente sencillo. Simplemente lo registro como una advertencia para que realmente aparezca.
fuente
Creo que podría haber estado pensando demasiado en esto. Una forma en que se me ocurrió que funciona, es simplemente tener una variable global, que acumule los datos de diagnóstico.
Algo como esto:
Gracias por las respuestas. Me han dado algunas ideas alternativas sobre cómo registrar información de pruebas unitarias en Python.
fuente
Usar registro:
Uso:
Si no lo configura
LOG_FILE
, el registro llegará astderr
.fuente
Puedes usar el
logging
módulo para eso.Entonces, en el código de prueba unitaria, use:
De forma predeterminada, las advertencias y los errores se envían a
/dev/stderr
, por lo que deben estar visibles en la consola.Para personalizar los registros (como el formato), pruebe el siguiente ejemplo:
fuente
Lo que hago en estos casos es tener un
log.debug()
mensaje con algunos mensajes en mi aplicación. Dado que el nivel de registro predeterminado esWARNING
, estos mensajes no se muestran en la ejecución normal.Luego, en la prueba unitaria, cambio el nivel de registro a
DEBUG
, para que dichos mensajes se muestren mientras se ejecutan.En las pruebas unitarias:
Vea un ejemplo completo:
Es decir
daikiri.py
, una clase básica que implementa un Daikiri con su nombre y precio. Existe un métodomake_discount()
que devuelve el precio de ese daikiri específico después de aplicar un descuento determinado:Luego, creo una prueba unitaria
test_daikiri.py
que verifica su uso:Entonces, cuando lo ejecuto, obtengo los
log.debug
mensajes:fuente
inspect.trace le permitirá obtener variables locales después de que se haya lanzado una excepción. A continuación, puede envolver las pruebas unitarias con un decorador como el siguiente para guardar esas variables locales para su examen durante la autopsia.
La última línea imprimirá los valores devueltos donde la prueba tuvo éxito y las variables locales, en este caso x, cuando falla:
Har det gøy :-)
fuente
¿Qué tal detectar la excepción que se genera a partir del error de aserción? En su bloque de captura, podría generar los datos como quisiera en cualquier lugar. Luego, cuando haya terminado, puede volver a lanzar la excepción. El corredor de pruebas probablemente no notaría la diferencia.
Descargo de responsabilidad: no he probado esto con el marco de prueba unitario de Python, pero lo he hecho con otros marcos de prueba unitaria.
fuente
Admitiendo que no lo he probado, la función de registro de los accesorios de prueba parece bastante útil ...
fuente
Ampliando la respuesta de @FC, esto funciona bastante bien para mí:
fuente