2010-10-01 16 views
20

¿Cómo hacer las pruebas unitarias cuando se tienepruebas unitarias con las dependencias entre las pruebas

  • alguna unidad general, pone a prueba
  • pruebas más sofisticadas comprobación casos extremos, dependiendo de las generales

Para dar un ejemplo, imagine probar un CSV-reader (me acaba de inventar una notación para la demostración),

def test_readCsv(): ... 

@dependsOn(test_readCsv) 
def test_readCsv_duplicateColumnName(): ... 

@dependsOn(test_readCsv) 
def test_readCsv_unicodeColumnName(): ... 

Espero que las pruebas secundarias se ejecuten solo si la prueba principal tiene éxito. La razón detrás de esto es que ejecutar estas pruebas lleva tiempo. Muchos informes de fallas que se remontan a una sola razón tampoco serían informativos. Por supuesto, podría calzar todos los casos extremos en la prueba principal, pero me pregunto si hay una forma más estructurada de hacerlo.

he descubierto que son relacionados, pero diferentes preguntas,

ACTUALIZACIÓN:

que he encontrado TestNG que tiene un gran soporte integrado para dependencias de prueba. Puede escribir pruebas de este tipo,

@Test{dependsOnMethods = ("test_readCsv")) 
public void test_readCsv_duplicateColumnName() { 
    ... 
} 

Respuesta

10

En lo personal, yo no me preocuparía por crear dependencias entre las pruebas unitarias. Esto suena como un olor a código para mí. Algunos puntos:

  • Si falla una prueba, deje que las otras fallen y tenga una buena idea de la magnitud del problema que ocasionó el cambio de código adverso.
  • Las fallas en las pruebas deberían ser la excepción más que la norma, entonces ¿por qué perder el esfuerzo y crear dependencias cuando la gran mayoría de las veces (¡con suerte!) No se deriva ningún beneficio. Si las fallas ocurren a menudo, su problema no es con las dependencias de prueba de la unidad, sino con las fallas de prueba frecuentes.
  • Las pruebas unitarias deben ejecutarse muy rápido. Si se están ejecutando lentamente, concéntrese en aumentar la velocidad de estas pruebas en lugar de evitar fallas posteriores. Haga esto desacoplando más su código y usando inyección de dependencia o burla.
+20

Sí, PERO: si algo falla y causa una cascada de fallas, no se garantiza que los mensajes de error se corrijan en el orden correcto para solucionarlos (especialmente si hacer cualquier descubrimiento automático de pruebas). Por ejemplo, tenemos un conjunto de pruebas unitarias que verifican si un entorno web está configurado correctamente, lo que (entre otras cosas) es útil para los nuevos empleados. Si te falta el archivo X y ese archivo está enlazado en 3 lugares, primero quieres arreglar el archivo que falta. Eso puede no ser obvio para un novato y, por lo tanto, disminuye la utilidad del conjunto de pruebas. –

+0

Hay algunos escenarios en los que se necesitan * dependencias * entre pruebas. Por ejemplo: probar un contenedor de API que inicia sesión en un servidor externo. Esa sesión de inicio de sesión tendría que ser compartida entre las pruebas. –

2

No estoy seguro de lo que el lenguaje que usted se refiere (y cuando no se menciona específicamente en su pregunta), pero para algo como PHPUnit hay una etiqueta que @depends solo ejecutará una prueba si la prueba dependiente ya pasó.

Dependiendo de qué idioma o la unidad de pruebas se utiliza también puede haber algo similar disponible

+0

El código de ejemplo es python;) – naught101

0

De acuerdo con las mejores prácticas y los principios de prueba de unidades, la prueba unitaria no debe depender de otras.

Cada caso de prueba debe verificar el comportamiento aislado del concreto.

Luego, si falla un caso de prueba sabrá exactamente qué fue lo que falló con nuestro código.

+3

Tengo el mismo problema que el OP. Tengo una prueba que prueba el constructor. Otra prueba que prueba un método en la clase. Obviamente, si el constructor falla, ambas pruebas fallarán, lo que OCULTA lo que está mal con mi código. La prueba del constructor debe fallar, la prueba del método debe omitirse. – Oddthinking

+0

Esto no tiene sentido en la pregunta. La segunda prueba puede ejecutarse por sí misma, independientemente de la primera, y verifica el comportamiento concreto y aislado. Sin embargo, si falla la primera prueba, se garantiza que la segunda prueba fallará, por lo que no tiene sentido ejecutarla. – Oddthinking

5

probóscide es una versión de Python TestNG (que es una biblioteca de Java).

Ver packages.python.org/proboscis/

Es compatible con las dependencias, por ejemplo

@test(depends_on=[test_readCsv]) 
public void test_readCsv_duplicateColumnName() { 
    ... 
} 
+0

No estoy seguro si me perdí algo, pero no pude encontrar la forma de compatibilidad con setup_class() y setup() con probóscide. Parecía tener un '@ before_class' pero no un' @ before'. – Zitrax

2

he implementado un plugin para Nose (Python) que añade soporte para las dependencias de prueba y prueba de priorización.

Como se menciona en las otras respuestas/comentarios, esta suele ser una mala idea; sin embargo, puede haber excepciones en las que desearía hacer esto (en mi caso fue el rendimiento para las pruebas de integración, con una gran sobrecarga para acceder a estado comprobable, minutos frente a horas).

Lo puede encontrar aquí: nosedep.

Un ejemplo es mínima:

def test_a: 
    pass 

@depends(before=test_a) 
def test_b: 
    pass 

Para garantizar que test_b siempre se ejecuta antes de test_a.

Cuestiones relacionadas