it-swarm-es.com

¿Cómo logra que sus pruebas funcionen de manera eficiente mientras rediseña?

Una base de código bien probada tiene una serie de beneficios, pero probar ciertos aspectos del sistema da como resultado una base de código que es resistente a algunos tipos de cambios.

Un ejemplo son las pruebas para resultados específicos, por ejemplo, texto o HTML. Las pruebas se escriben a menudo (¿ingenuamente?) Para esperar un bloque particular de texto como salida para algunos parámetros de entrada, o para buscar secciones específicas en un bloque.

Cambiar el comportamiento del código, para cumplir con nuevos requisitos o porque las pruebas de usabilidad han dado como resultado un cambio en la interfaz, también requiere cambiar las pruebas, tal vez incluso pruebas que no son específicamente pruebas unitarias para el código que se cambia.

  • ¿Cómo gestiona el trabajo de encontrar y reescribir estas pruebas? ¿Qué pasa si no puede simplemente "ejecutarlos todos y dejar que el marco los solucione"?

  • ¿Qué otros tipos de código sometido a prueba dan como resultado pruebas habitualmente frágiles?

15
Alex Feinman

Sé que la gente de TDD odiará esta respuesta, pero una gran parte para mí es elegir cuidadosamente dónde probar algo.

Si me vuelvo demasiado loco con las pruebas unitarias en los niveles inferiores, no se puede hacer ningún cambio significativo sin alterar las pruebas unitarias. Si la interfaz nunca está expuesta y no está destinada a ser reutilizada fuera de la aplicación, esto es una sobrecarga innecesaria para lo que podría haber sido un cambio rápido de otra manera.

Por el contrario, si lo que está tratando de cambiar está expuesto o reutilizado, cada una de esas pruebas que tendrá que cambiar es evidencia de algo que podría estar rompiendo en otro lugar.

En algunos proyectos, esto puede equivaler a diseñar sus pruebas desde el nivel de aceptación hacia abajo en lugar de desde las pruebas unitarias hacia arriba. y tener menos pruebas unitarias y más pruebas de estilo de integración.

No significa que aún no pueda identificar una sola característica y código hasta que esa característica cumpla con sus criterios de aceptación. Simplemente significa que en algunos casos no terminas midiendo los criterios de aceptación con pruebas unitarias.

10
Bill

Acabo de completar una revisión importante de mi pila SIP, reescribiendo todo el transporte TCP. (Esto fue casi una refactorización, en una escala bastante grande, en relación con la mayoría de las refactorizaciones.)

En resumen, hay un TIdSipTcpTransport, subclase de TIdSipTransport. Todos los TIdSipTransports comparten un conjunto de pruebas común. Dentro de TIdSipTcpTransport había una serie de clases: un mapa que contiene pares de conexión/mensaje de inicio, clientes TCP, un servidor TCP, etc.).

Esto es lo que hice:

  • Eliminé las clases que iba a reemplazar.
  • Se eliminaron las suites de prueba para esas clases.
  • Izquierda el conjunto de pruebas específico de TIdSipTcpTransport (y todavía existía el conjunto de pruebas común a todos los TIdSipTransports).
  • Ejecutó las pruebas TIdSipTransport/TIdSipTcpTransport para asegurarse de que todas fallaron.
  • Comentó todas menos una prueba TIdSipTransport/TIdSipTcpTransport.
  • Si tuviera que agregar una clase, agregaría pruebas de escritura para desarrollar la funcionalidad suficiente para que pasara la única prueba sin comentarios.
  • Enjabonar, enjuagar, repetir.

Por lo tanto, sabía lo que aún tenía que hacer, en forma de las pruebas comentadas (*), y sabía que el nuevo código estaba funcionando como se esperaba, gracias a las nuevas pruebas que escribí.

(*) Realmente, no necesitas comentarlos. Simplemente no los ejecutes; 100 pruebas fallidas no es muy alentador. Además, en mi configuración particular, compilar menos pruebas significa un bucle test-write-refactor más rápido.

4
Frank Shearar

Cuando las pruebas son frágiles, generalmente encuentro que es porque estoy probando algo incorrecto. Tomemos, por ejemplo, la salida HTML. Si verifica la salida HTML real, su prueba será frágil. Pero no está interesado en el resultado real, está interesado en si transmite la información que debería. Desafortunadamente, hacer eso requiere hacer afirmaciones sobre el contenido del cerebro del usuario y, por lo tanto, no puede hacerse automáticamente.

Usted puede:

  • Genere el HTML como una prueba de humo para asegurarse de que realmente se ejecute
  • Utilice un sistema de plantillas, de modo que pueda probar el procesador de plantillas y los datos enviados a la plantilla, sin tener que probar la plantilla exacta en sí.

Lo mismo sucede con SQL. Si afirma el SQL real que sus clases intentan hacer, tendrá problemas. Realmente quieres afirmar los resultados. Por lo tanto, utilizo una base de datos de memoria SQLITE durante mis pruebas unitarias para asegurarme de que mi SQL realmente hace lo que se supone que debe hacer.

3
Winston Ewert