unittest unitarias pruebas integracion automatizadas python unit-testing nose pytest

unitarias - Marco de prueba de unidad de Python preferido



pruebas unitarias en python (10)

Hasta ahora he estado usando el módulo de prueba de unidad incorporado (pyUnit) para probar el código Python de unidad. Sin embargo, para casos simples parece una exageración. Siendo un derivado de xUnit, parece un poco pesado para la naturaleza dinámica de Python, donde esperaría escribir menos para lograr los mismos efectos. Por otro lado, está integrado, te hace escribir tus pruebas de forma organizada y se prueba por tiempo.

Las principales alternativas que he visto en línea son:

¿Cuál de los marcos prefieres y por qué?

Actualización 10.12.2011: con la reciente adición de prueba de autodescubrimiento y muchas características nuevas en unittest (en Python 2.7 y 3.2), en mi humilde opinión tiene menos sentido utilizar una biblioteca externa.

Con respecto a doctest: no lo considero un marco de prueba de unidad por sí mismo. Definitivamente no lo usaría para escribir un gran conjunto de pruebas para una aplicación de tamaño considerable. doctest es más adecuado para asegurarse de que los ejemplos que proporciona en la documentación funcionan. Tiene su lugar para esta necesidad, pero no es un competidor para unittest, py.test y otros marcos.


Creo que es una cuestión de elección realmente. He usado todos los marcos de prueba principales, todo se reduce a cuál crees que hace el trabajo con menos codificación. Dicho esto, prefiero doctest también.

Pero desde entonces he descubierto pytest y no he mirado atrás nunca. Todavía uso doctest a veces, pero prefiero usar pytest en nuevos proyectos.


El unittest.TestCase es una clase. Siéntase libre de subclasificarlo con sus propias características adicionales que le permiten "escribir menos para lograr los mismos efectos".


Estoy de acuerdo en que una de las mejores características de la nariz es su sistema de complementos. Por ejemplo, comencé a aprender Python cuando se lanzó Google App Engine y había un complemento de Nose para admitir GAE casi de inmediato. Así que Nose, con sus complementos, me ayudó a comenzar a realizar desarrollos basados ​​en pruebas con una nueva plataforma como GAE desde el principio. El complemento de cobertura estaba allí cuando yo también estaba listo para ello.


Inicialmente comenzamos nuestro marco de automatización usando unittest y nosetest . Hemos subclasificado todas nuestras clases de prueba de unittest, ya que unittest ofrece una gran sintaxis para las aserciones. Para la ejecución real de las pruebas, utilizamos la nariz, que fue bastante buena en términos de informes y especificación de las pruebas que se deben ejecutar. La lógica de la generación de pruebas también fue bastante buena: usar el método de rendimiento fue fácil de usar. El único problema con la generación de prueba de la nariz es que la clase de prueba no puede heredar de unittest: la generación de prueba falla entonces. Sólo las aserciones de la nariz se pueden utilizar aquí.

Tuvimos problemas importantes con la nariz cuando queríamos paralelizar las pruebas. El informe fue extremadamente complicado cuando las pruebas se ejecutaron en paralelo. Además, si está creando ciertos recursos en los métodos de configuración, la paralelización también falla con errores extraños. Parecía muy complejo usar la nariz para paralelizar las ejecuciones de prueba; intentamos casi todo. Entonces, finalmente, uno de los miembros de nuestro equipo golpeó py.test. En muy poco tiempo pudo realizar los cambios necesarios en un conjunto de 30 pruebas para ejecutarlas en paralelo. Comenzó la carrera y para su sorpresa, la carrera pasó en un registro de 15 minutos de los 75 minutos anteriores que solía tomar. Él fue capaz de ejecutar las 30 pruebas en paralelo con éxito con la menor cantidad de esfuerzo y molestia. La sintaxis también fue simple y el informe fue excelente: superó con creces el informe del marco de la nariz.

Así que diría que la combinación ganadora es py.test con unittest.


Interesante que nadie ha respondido aún para defender py.test . En la lista de correo de testing-in-python es bastante popular, por ejemplo, este hilo reciente "¿por qué usas py.test?" . Las respuestas más comunes incluyeron:

  • Fácil soporte para pruebas distribuidas.
  • buena arquitectura de plugins
  • aserciones más fáciles (solo assert x == 42 , no assertEqual() )
  • funcargs (desde 2.3 o 2.4 dispositivos llamados, algo diferente a lo que otros marcos de prueba llaman dispositivos)

Siempre hay doctest si desea mantener sus pruebas de unidad cerca del código.

HTH


Solo uso el unittest estándar. No estoy seguro de cómo escribiría las pruebas con la misma eficacia con otro estilo, tal vez cada prueba en una función, pero ¿cómo manejaría la configuración / desmontaje?


Una de las características más agradables de nose es su sistema de complementos: por ejemplo, el complemento de cobertura le muestra qué parte de su código está cubierto por pruebas de unidad. Después de escribir muchas pruebas de unidad, a menudo resulta impactante ver qué parte de su código no está cubierto ...


nose2 ha reemplazado a nose y admite pruebas parametrizadas, lo que significa que puede ejecutar las mismas afirmaciones con diferentes parámetros. Esto le permite cubrir más escenarios con mucho menos código.


nose no es realmente un marco de prueba de unidad. Es un corredor de prueba y un gran en eso. Puede ejecutar pruebas creadas usando unittest , py.test o doctest .

Mi preferencia por el marco de pruebas de unidad es el módulo de prueba de unidad estándar (también conocido como pyUnit ). Es similar a otros marcos de trabajo de xUnit y es fácil de relacionar con personas sin antecedentes de Python. También hay un soporte bastante bueno para ello en Eclipse / PyDev.

En py.test , encuentro varios niveles de configuración / desmontaje muy confusos. También encuentro que conduce a pruebas unitarias altamente desestructuradas y difíciles de leer.

doctest está bien para cosas simples, pero me parece que es muy limitante y realmente no se puede escalar para códigos complejos y altamente interactivos.