¿Cómo probar las pruebas?

52

Probamos nuestro código para hacerlo más correcto (en realidad, es menos probable que sea incorrecto ). Sin embargo, las pruebas también son códigos, también pueden contener errores. Y si sus pruebas tienen errores, difícilmente mejorarán su código.

Puedo pensar en tres tipos posibles de errores en las pruebas:

  1. Errores lógicos, cuando el programador no entendió la tarea en cuestión y las pruebas hacen lo que pensaron que deberían hacer, lo que está mal;

  2. Errores en el marco de prueba subyacente (p. ej., una abstracción burlona);

  3. Errores en las pruebas: la prueba está haciendo un poco diferente de lo que el programador cree que es.

Los errores de tipo (1) parecen ser imposibles de prevenir (a menos que el programador simplemente ... se vuelva más inteligente). Sin embargo, (2) y (3) pueden ser manejables. ¿Cómo lidiar con este tipo de errores? ¿Tienes alguna estrategia especial para evitarlos? Por ejemplo, ¿escribe algunas pruebas especiales "vacías", que solo verifican las presuposiciones del autor de la prueba? Además, ¿cómo aborda la depuración de un caso de prueba roto?

    
pregunta Ryszard Szopa 13.10.2010 - 01:04

10 respuestas

16

Las pruebas ya están probadas. Las pruebas están protegidas por diseño contra los errores, ya que las pruebas solo detectan diferencias entre el código y nuestras expectativas. Si hay problemas tenemos un error. El error podría estar en el código o con la misma probabilidad en las pruebas.

  1. Existen algunas técnicas que le impiden agregar el mismo error tanto en su código como en sus pruebas:

    1. El cliente debe ser una persona diferente a la del implementador.
    2. Primero escriba las pruebas y luego el código (como en Test Driven Development).
  2. No es necesario probar la plataforma subyacente. Las pruebas no solo ejercitan el código escrito por usted, sino que también ejecutan el código desde la plataforma. Si bien no es necesario que atrapes errores en la plataforma de prueba, es muy difícil escribir código y pruebas que siempre ocultan un error en la plataforma, en otras palabras, es muy difícil tener un error sistemático en tus pruebas / código y en la plataforma, y la probabilidad se reduce con cada prueba que cree. Incluso si tratas de hacer esto, tendrías una tarea muy difícil.

  3. Podría tener errores en las pruebas, pero generalmente se detectan fácilmente porque las pruebas están probadas por el código desarrollado. Entre el código y las pruebas tienes una retroalimentación de auto ejecución. Ambos hacen predicciones sobre cómo debe comportarse una llamada específica de una interfaz. Si la respuesta es diferente, no es necesario tener un error en el código. También podría tener un error en la prueba.

respondido por el raisercostin 13.10.2010 - 02:06
24

Intente hacer las pruebas individuales lo más pequeñas (cortas) que sea posible.

Esto debería reducir las posibilidades de crear un error en primer lugar. Incluso si logras crear uno, es más fácil de encontrar. Se supone que las pruebas unitarias son pequeñas y específicas, con poca tolerancia al fallo y la desviación.

Al final, es probable que sea solo una cuestión de experiencia. Cuantas más pruebas escribas, mejor te vuelves, menos posibilidades tienes de hacer pruebas de mierda.

    
respondido por el dr Hannibal Lecter 13.10.2010 - 01:17
19

Una táctica es escribir la prueba antes del código que prueba, y asegurarse de que la prueba falle primero por la razón correcta. Si utiliza TDD , debería obtener al menos este nivel de prueba de pruebas.

Una forma más exhaustiva de probar la calidad de un conjunto de pruebas es utilizar prueba de mutación .

    
respondido por el Don Roby 13.10.2010 - 04:13
4

Para los números 1 y 3: las pruebas unitarias no deben contener ninguna lógica; si lo hace, probablemente esté probando más de una cosa en su prueba unitaria. Una de las mejores prácticas para las pruebas unitarias es tener solo una prueba por unidad.

Vea este video de Roy Osherove para obtener más información sobre cómo Escribir bien las pruebas unitarias.

    
respondido por el Piers Myers 13.10.2010 - 02:29
3

En términos de # 1: creo que es una buena idea emparejar / revisar el código para este lado de las cosas. Es fácil hacer presuposiciones o simplemente hacer las cosas mal, pero si tiene que explicar qué está haciendo su prueba, cuál es el punto, es más probable que responda si apunta al objetivo equivocado.

    
respondido por el Sam J 13.10.2010 - 01:34
2

Debe haber un punto en el que uno debe dejar de intentar realizar una prueba unitaria. Debe saber cuándo dibujar la línea. ¿Debemos escribir casos de prueba para probar casos? ¿Qué pasa con los nuevos casos de prueba escritos para probar los casos? ¿Cómo los probaremos?

if (0 > printf("Hello, world\n")) {
  printf("Printing \"Hello, world\" failed\n");
}

Editar: actualizado con la explicación sugerida por el comentario.

    
respondido por el aufather 13.10.2010 - 01:09
2

Hey.
Tienes que aplicaciones:

  • Su producto
  • Su prueba para ese producto.

Cuando está ejecutando pruebas contra su producto, en realidad no está interesado en la prueba en sí, sino en la interacción entre su producto y sus pruebas. Si la prueba falla, no dice que la aplicación tenga un error. Dice que la interacción entre el producto y la prueba no tuvo éxito . Ahora es tu trabajo determinar qué salió mal. Puede ser:

  • la aplicación no se comporta como esperaba (esta expectativa se expresa en su prueba)
  • la aplicación se comporta correctamente, simplemente no has documentado este comportamiento correctamente (en tus pruebas)

Para mí, las pruebas que fallan no son simples comentarios, que esto y eso están mal . Es un indicador de que hay inconsistencia, y necesito examinar ambas para verificar que la solicitud haya fallado. Al final, soy responsable de verificar que la aplicación sea correcta, las pruebas son solo una herramienta para resaltar las áreas que vale la pena revisar.

Las pruebas solo verifican algunas partes de la aplicación. Pruebo la aplicación, pruebo las pruebas.

    
respondido por el yoosiba 20.02.2011 - 20:16
2

Las pruebas no deberían ser lo suficientemente "inteligentes" para albergar errores.

El código que estás escribiendo implementa un conjunto de especificaciones. (Si X entonces Y, a menos que Z en cuyo caso Q, etc, etc.). Todo lo que la prueba debe intentar es determinar que X realmente es Y a menos que Z, en cuyo caso Q. Esto significa que todo lo que debe hacer una prueba es configurar X y verificar Y.

Pero eso no cubre todos los casos, probablemente esté diciendo, y tendría razón. Pero si hace que la prueba sea lo suficientemente "inteligente" para saber que X solo debería ser Y si no Z, entonces básicamente está reimplementando la lógica de negocios en la prueba. Esto es problemático por razones que veremos más adelante. No debe mejorar la cobertura del código haciendo su primera prueba "más inteligente", sino que debe agregar una segunda prueba tonta que establece X y Z y verifica Q. De esa manera, tendrá dos pruebas, una que cubre el caso general ( a veces también conocido como el camino feliz) y uno que cubre el caso del borde como una prueba separada.

Hay varias razones para esto, en primer lugar, ¿cómo se determina si una prueba fallida se debe a un error en la lógica empresarial o un error en las pruebas? Obviamente, la respuesta es que si las pruebas son lo más simples posible, es muy poco probable que alberguen errores. Si cree que sus pruebas necesitan pruebas, entonces las pruebas son incorrectas .

Otras razones incluyen que solo estás replicando el esfuerzo (como ya mencioné, escribir una prueba lo suficientemente inteligente como para ejercer todas las posibilidades en una sola prueba es básicamente replicar la lógica de negocios que intentas probar en primer lugar), si los requisitos cambian, entonces las pruebas deberían ser fáciles de cambiar para reflejar los nuevos requisitos, las pruebas sirven como una especie de documentación (son una forma formal de decir cuál es la especificación de la unidad bajo prueba) y así sucesivamente.

TL: DR: Si tus pruebas necesitan pruebas, lo estás haciendo mal. Escribe pruebas tontas .

    
respondido por el GordonM 13.03.2017 - 14:25
0

No es una respuesta (no tengo el privilegio de comentar), pero me preguntaba si olvidó otras razones para desarrollar casos de prueba ...
Una vez que haya resuelto todos los errores en las pruebas, puede realizar una prueba de regresión de su aplicación fácilmente. Las suites de pruebas automatizadas lo ayudarían a encontrar problemas antes, antes de la integración. Los cambios en los requisitos son relativamente más fáciles de probar, ya que los cambios pueden volverse más nuevos, la versión alterada de los casos de prueba más antiguos que pasan, y los casos más antiguos se quedan para detectar fallas.

    
respondido por el CMR 20.02.2011 - 20:55
0

Respuesta corta: El código de producción prueba las pruebas .

Compare esto con el modelo de crédito / débito utilizado en economía. Los mecanismos son muy simples: si el crédito difiere del débito, hay algo incorrecto.

él mismo va para las pruebas unitarias: si una prueba falla, indica que algo está mal. Puede ser el código de producción, pero también puede ser el código de prueba. Esta última parte es importante.

Tenga en cuenta que las pruebas unitarias no pueden encontrar sus errores de tipo (1). Para evitar este tipo de errores, necesitas otras herramientas.

    
respondido por el vidstige 27.02.2012 - 15:48

Lea otras preguntas en las etiquetas