Python – doctest vs. unittest

Estoy intentando comenzar con las pruebas de unidad 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?

Ambos son valiosos. Utilizo doctest y la nariz en lugar de unittest. Uso doctest para los casos en los que la prueba da un ejemplo de uso que es realmente útil como documentación. En general, no hago estas pruebas exhaustivas, con el único objective de proporcionar información. Estoy utilizando efectivamente doctest a la inversa: no para comprobar si mi código es correcto en función de mi doctest, sino para verificar que mi documentación sea correcta según el código.

La razón es que creo que las pruebas exhaustivas de documentos abarrotarán su documentación demasiado, por lo que terminará con cadenas de documentos inutilizables o pruebas incompletas.

Para probar realmente el código , el objective es probar minuciosamente cada caso, en lugar de ilustrar lo que se hace con el ejemplo, que es un objective diferente que creo que otros marcos pueden alcanzar mejor.

Uso unittest casi exclusivamente.

De vez en cuando, pondré algunas cosas en una cadena de documentos que se puede utilizar con doctest.

El 95% de los casos de prueba son unittest.

¿Por qué? Me gusta mantener docstrings un poco más cortos y más al punto. A veces los casos de prueba ayudan a aclarar una cadena de documentación. La mayoría de las veces, los casos de prueba de la aplicación son demasiado largos para una cadena de documentación.

Otra ventaja de doctesting es que usted se asegura 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 su código hagan cosas diferentes. 🙂

Trabajo como bioinformático, y la mayoría del código que escribo son scripts de “una sola vez, una tarea”, código que se ejecutará solo una o dos veces y que ejecuta una sola tarea específica.

En esta situación, escribir pruebas unitarias grandes puede ser excesivo, y las pruebas documentales son un compromiso útil. Son más rápidos de escribir, y como generalmente están incorporados en el código, permiten mantener un ojo en el comportamiento del código, sin tener que tener otro archivo abierto. Eso es útil cuando se escribe un pequeño script.

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

Así que, para resumir mi respuesta: los doctest son útiles cuando tienes que escribir pequeños scripts, y cuando tienes que pasarlos o mostrárselos a los investigadores que no son informáticos.

Si recién está comenzando con la idea de las pruebas unitarias, empezaría con doctest porque es muy fácil de usar. Naturalmente, también proporciona algún nivel de documentación. Y para realizar pruebas más completas con doctest , puede colocar las pruebas en un archivo externo para que no se llene su documentación.

Yo sugeriría la prueba de la unidad si viene de un historial de haber usado JUnit o algo similar, donde quiere poder escribir pruebas de unidad en general de la misma manera que lo ha hecho en otros lugares.

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

Usar ambos es una opción válida y bastante simple. El módulo doctest proporciona los métodos DoctTestSuite y DocFileSuite que crean un testuite compatible con unittest a partir de un módulo o archivo, respectivamente.

Así que 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 unas pocas pruebas doctest ayudan a 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.

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

  • Utilizo unittest como marco de pruebas de unidad, lo que significa que me ayuda a determinar rápidamente el impacto de cualquier modificación en el rest del código.

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

Los beneficios ampliamente documentados del desarrollo basado en pruebas que obtengo de unittest . doctest resuelve el peligro mucho más sutil de tener comentarios desactualizados que induzcan a error al mantenimiento del código.

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

Doctest puede algunas veces conducir a un resultado equivocado. 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 algún tipo racional que se imprime como un 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.

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 el código demasiado.