Python - doctest vs. unittest [cerrado]

160

Estoy tratando de comenzar con las pruebas unitarias en Python y me preguntaba si alguien podría explicar las ventajas y desventajas de doctest y unittest.

¿Para qué condiciones usarías cada uno?

Sean
fuente

Respuestas:

177

Ambos son valiosos. Utilizo doctest y nose tomando el lugar de unittest. Utilizo doctest para casos en los que la prueba está dando un ejemplo de uso que es realmente útil como documentación. En general, no hago estas pruebas exhaustivas, con el único objetivo de informar. Efectivamente estoy usando doctest a la inversa: no para probar que mi código es correcto según mi doctest, sino para verificar que mi documentación sea correcta según el código.

La razón es que creo que los doctest completos saturarán demasiado tu documentación, por lo que terminarás con cadenas de documentos inutilizables o pruebas incompletas.

Para probar realmente el código , el objetivo es probar a fondo cada caso, en lugar de ilustrar lo que se hace con el ejemplo, que es un objetivo diferente que creo que otros marcos cumplen mejor.

Brian
fuente
29
Hay mucho menos repetitivo, y las pruebas me parecen mucho más simples de escribir (y leer). El bajo costo de inicio para escribir pruebas (es decir, simplemente escribir una función "test_foo ()" y listo) también ayuda a combatir la tentación de hacer los bits de código interesantes antes de concretar las pruebas.
Brian
66
Creo que esta es una respuesta fantástica.
James Brady el
¿Qué otros marcos de prueba utilizas? ¿O es exclusivamente nariz?
Joe
66
Dada la antigüedad de esta respuesta, probablemente valga la pena mencionar que gran parte del "patrón repetitivo" de las versiones anteriores de unittest ya no existe. Todavía me gusta más la nariz, pero es casi una sacudida.
Adam Parkin
1
FYI nose ha estado en "modo de mantenimiento" durante los últimos años y probablemente cesará todo el desarrollo (ausente la intervención de un tercero). Sus mantenedores recomiendan que los nuevos proyectos usen una alternativa.
Seis
48

Yo uso unittest casi exclusivamente.

De vez en cuando, pondré algunas cosas en una cadena de documentos que puede ser utilizada por doctest.

El 95% de los casos de prueba son unittest.

¿Por qué? Me gusta mantener las cadenas de documentos algo más cortas y más precisas. A veces, los casos de prueba ayudan a aclarar una cadena de documentos. La mayoría de las veces, los casos de prueba de la aplicación son demasiado largos para una cadena de documentos.

S.Lott
fuente
Sería genial ver un ejemplo, qué crees que es adecuado docstringy qué no. De hecho, me gusta docstring en términos que muestra explícitamente cómo usar una interfaz, pero usarlo tanto para eso como para las pruebas unitarias podría no encajar bien.
user1767754
33

Otra ventaja del doctesting es que puede asegurarse de que su código haga lo que su documentación dice que hace. Después de un tiempo, los cambios de software pueden hacer que su documentación y código hagan cosas diferentes. :-)

Jason Baker
fuente
66
+1 de mi parte - excelente punto
doug
28

Trabajo como bioinformático, y la mayor parte del código que escribo son scripts de "una vez, una tarea", código que se ejecutará solo una o dos veces y que ejecutará una única tarea específica.

En esta situación, escribir grandes pruebas unitarias puede ser excesivo, y las pruebas de documentación son un compromiso útil. Son más rápidos de escribir, y dado que generalmente se incorporan al código, permiten vigilar siempre cómo debe comportarse el código, sin tener que tener otro archivo abierto. Eso es útil al escribir pequeños guiones.

Además, los doctest son útiles cuando tienes que pasar tu guión a un investigador que no sea experto en programación. A algunas personas les resulta muy difícil entender cómo se estructuran las pruebas unitarias; Por otro lado, los doctest son ejemplos simples de uso, por lo que las personas pueden simplemente copiarlos y pegarlos para ver cómo usarlos.

Entonces, para resumir mi respuesta: los doctests son útiles cuando tienes que escribir pequeños guiones, y cuando tienes que pasarlos o mostrarlos a investigadores que no son informáticos.

dalloliogm
fuente
66
"los doctests son útiles cuando tienes que escribir pequeños guiones y cuando tienes que pasarlos o mostrarlos a investigadores que no son informáticos". Excelente punto Hago lo mismo y los programadores que no son de Python siempre se sorprenden de que la documentación se pueda ejecutar.
Daniel Canas
14

Si recién está comenzando con la idea de las pruebas unitarias, comenzaría doctestporque es muy fácil de usar. También, naturalmente, proporciona cierto nivel de documentación. Y para realizar pruebas más exhaustivas con doctest, puede colocar pruebas en un archivo externo para que no abarrote su documentación.

Sugeriría que unittestsi viene de un contexto de haber usado JUnit o algo similar, donde desea poder escribir pruebas unitarias en general de la misma manera que lo ha hecho en otros lugares.

Greg Hewgill
fuente
44
Me animaron en esta dirección ( doctestpara empezar), pero finalmente lo lamenté. Para casos de prueba no triviales, perdí el resaltado de sintaxis y la finalización automática de mi editor. Cuando las pruebas estaban en un archivo separado, ya no podía ejecutarlo directamente desde el editor; cada vez tenía que cambiar el contexto al archivo fuente correspondiente.
Pensamiento extraño
7

Yo uso unittest exclusivamente; Creo que doctest satura demasiado el módulo principal. Esto probablemente tiene que ver con escribir pruebas exhaustivas.

Tony Arkles
fuente
7

Usar ambos es una opción válida y bastante simple. El doctestmódulo proporciona el DoctTestSuiteyDocFileSuite métodos que crean un conjunto de pruebas compatible con unittest a partir de un módulo o archivo, respectivamente.

Por lo tanto, uso ambos y normalmente uso doctest para pruebas simples con funciones que requieren poca o ninguna configuración (tipos simples para argumentos). De hecho, creo que algunas pruebas doctest ayudan documentar la función, en lugar de restarle valor.

Pero para casos más complicados y para un conjunto más completo de casos de prueba, utilizo unittest que proporciona más control y flexibilidad.

davidavr
fuente
7

No uso doctest como reemplazo de unittest. Aunque se superponen un poco, los dos módulos no tienen la misma función:

  • Lo uso unittestcomo un marco de prueba de unidad, lo que significa que me ayuda a determinar rápidamente el impacto de cualquier modificación en el resto del código.

  • Utilizo doctestcomo garantía de que los comentarios (es decir, las cadenas de documentos) siguen siendo relevantes para la versión actual del código.

Los beneficios ampliamente documentados del desarrollo impulsado por pruebas que obtengo unittest. doctestresuelve el peligro mucho más sutil de tener comentarios desactualizados que confunden el mantenimiento del código.

rahmu
fuente
4

Casi nunca uso doctests. Quiero que mi código sea autodocumentado, y las cadenas de documentos proporcionan la documentación al usuario. La OMI que agrega cientos de líneas de pruebas a un módulo hace que las cadenas de documentos sean mucho menos legibles. También encuentro que las pruebas unitarias son más fáciles de modificar cuando es necesario.

JimB
fuente
4

DoctestAlgunas veces puede conducir a un resultado incorrecto. Especialmente cuando la salida contiene secuencias de escape. Por ejemplo

def convert():
    """
    >>> convert()
    '\xe0\xa4\x95'
    """
    a = '\xe0\xa4\x95'
    return a
import doctest
doctest.testmod()

da

**********************************************************************
File "hindi.py", line 3, in __main__.convert
Failed example:
    convert()
Expected:
    'क'
Got:
    '\xe0\xa4\x95'
**********************************************************************
1 items had failures:
   1 of   1 in __main__.convert
***Test Failed*** 1 failures. 

Tampoco verifica el tipo de salida. Simplemente compara las cadenas de salida. Por ejemplo, ha hecho un tipo racional que imprime igual que un número entero si es un número entero. Entonces suponga que tiene una función que devuelve racional. Por lo tanto, un doctest no diferenciará si la salida es un número entero racional o un número entero.

Duro
fuente
55
Puede usar cadenas de documentos sin formato ( r""" ... """) para solucionar el primer problema.
icktoofay
Funciona bien en Python 3.4. Para que funcione también en Python 2.7, utilícelo '\\xe0\\xa4\\x95'en su cadena de documentos.
Cees Timmerman
También descubrí que los literales unicode tampoco funcionan con doctests (incluso con la línea de comentario correcta 'codificación utf-8' en la parte superior del archivo. En general, los doctest no son tan compatibles como las pruebas unitarias, por lo que hay algunos errores eso no se arregla.
RichVel
2

Prefiero los sistemas basados ​​en descubrimiento ("nose" y "py.test", usando el primero actualmente).

doctest es bueno cuando la prueba también es buena como documentación, de lo contrario, tienden a saturar demasiado el código.

perezoso1
fuente
la nariz se ve increíblemente útil; Todavía no he tenido la oportunidad de usarlo, pero tengo muchas esperanzas :)
Tony Arkles
nose es prácticamente el marco de prueba más fácil de usar, en mi opinión. Hace que escribir y ejecutar casos de prueba sea bastante fácil.
Kamil Kisiel