Hemos acumulado una cantidad sustancial de pruebas unitarias para nuestro programa principal a lo largo de los años. Varios miles. El problema es que no tenemos una idea clara de qué pruebas tenemos porque hay muchas. Y eso es un problema porque no sabemos dónde somos débiles en las pruebas (o dónde tenemos duplicados).
Nuestra aplicación es un motor de informes. Por lo tanto, puede tener una plantilla que se utiliza para probar el análisis (leemos todas las propiedades de la tabla), combinando datos (¿mantuvimos las propiedades correctas de la tabla en la combinación), formateando la página final (es la tabla colocada correctamente en la página ), y / o el formato de salida (es el archivo DOCX creado correcto).
Agregue a esto lo que necesitamos probar. Tome el relleno alrededor de una celda de la tabla (usamos Word, Excel y PowerPoint para el diseño del informe). Tenemos que probar el relleno a través del salto de página, para una tabla dentro de una celda, celdas fusionadas verticalmente, celdas fusionadas horizontalmente, una celda fusionada vertical y horizontalmente que contiene una tabla con celdas fusionadas vertical y horizontalmente en la tabla interna, donde esa tabla se rompe en una página.
Entonces, ¿en qué categoría entra esa prueba? ¿Relleno de tabla, saltos de página, celdas anidadas, celdas fusionadas verticalmente, celdas fusionadas horizontales o algo más?
¿Y cómo documentamos estas categorías, nombramos las pruebas unitarias, etc.?
Actualización: varias personas han sugerido usar herramientas de cobertura para verificar que tengamos cobertura total. Desafortunadamente, esto es de uso limitado en nuestro caso porque los errores tienden a deberse a combinaciones específicas, por lo que es un código que ha sido probado, pero no en esa combinación.
Por ejemplo, ayer tuvimos un cliente que comenzó un marcador de Word al final de un ciclo forEach en su plantilla (un documento de Word) y lo finalizó al comienzo del siguiente ciclo forEach. Todo esto usó código que tiene pruebas unitarias en su contra, pero no habíamos pensado en la combinación de una plantilla que expandía un marcador que comenzaba a iniciarse 25 veces, luego terminaba 10 veces (los dos bucles forEach tenían un número diferente de filas).
fuente
Respuestas:
En general, tiendo a reflejar el árbol de origen para mis pruebas unitarias. Entonces, si tuviera src / lib / fubar, tendría una prueba / lib / fubar que contendría las pruebas unitarias para fubar.
Sin embargo, lo que parece estar describiendo son pruebas más funcionales. En ese caso, tendría una tabla multidimensional que enumerara todas sus posibles condiciones. Entonces, los que no tienen pruebas no tienen sentido o necesitan una nueva prueba. Por supuesto, puede colocarlos en conjuntos de conjuntos de pruebas.
fuente
La estructura más común parece ser el espejo de directorio
src
ytest
.Sin embargo, hay una estructura alternativa que he visto que ahora creo que es mejor.
Dado que las pruebas unitarias tienden a reflejar la clase que están probando, colocarlas en el mismo directorio brinda un acceso mucho más fácil a los archivos para que pueda trabajar en ambos lados.
fuente
En .NET, tiendo a reflejar, o al menos aproximar, la estructura del espacio de nombres para el código fuente en los proyectos de prueba, debajo de un espacio de nombres maestro "Tests.Unit" o "Tests.Integration". Todas las pruebas unitarias van en un proyecto, con la estructura básica del código fuente replicada como carpetas dentro del proyecto. Lo mismo para las pruebas de integración. Entonces, una solución simple para un proyecto podría verse así:
Para cualquier AAT o AEET que esté codificado con un marco de pruebas unitarias, esto cambia un poco; por lo general, esas pruebas reflejan un conjunto de pasos que probarán la funcionalidad de un nuevo caso de uso o historia. Por lo general, estructuro estas pruebas en un
MyProduct.Tests.Acceptance
proyecto como tal, con pruebas para cada historia, posiblemente agrupadas por hito o historia "épica" a la que pertenecía la historia en desarrollo. Sin embargo, esas son realmente solo pruebas de súper integración, por lo que si prefiere estructurar las pruebas de una manera más orientada a objetos en lugar de a historias, ni siquiera necesita unMyProduct.Tests.Acceptance
proyecto similar; simplemente colóquelosMyProduct.Tests.Integration
bajo el alcance del objeto de más alto nivel bajo prueba.fuente
No hay razón para que una prueba unitaria sea solo en una categoría. Todas las principales herramientas de prueba Unidad de Apoyo a la creación de conjuntos de pruebas , las cuales vinculan las pruebas para una categoría en particular. Cuando se ha cambiado un área particular de código, el desarrollador debe ejecutar esa suite primero y, a menudo, para ver qué se ha roto. Cuando un acolchado preocupaciones de prueba y se rompe y anidación, por todos los medios la ponen en las tres suites.
Dicho esto, el objetivo de las pruebas unitarias es ejecutarlas todo el tiempo, es decir, deben ser lo suficientemente pequeñas y rápidas para que sea posible ejecutarlas todas antes de cometer cualquier código. En otras palabras, realmente no importa de qué categoría sea una prueba, debe ejecutarse antes de comprometerse de todos modos. Las suites son realmente solo una muleta que usa si por alguna razón no puede escribir pruebas que sean tan rápidas como deberían.
En cuanto a la cobertura, existen muy buenas herramientas de cobertura que le indican qué porcentaje de líneas se ejercieron realmente al ejecutar sus pruebas; este es un indicador obvio de qué tipo de pruebas aún le faltan.
En cuanto a la asignación de nombres, no hay un valor particular en gastar esfuerzo en los nombres de las pruebas unitarias. Todo lo que quiere escuchar de sus exámenes es "5235 de 5235 exámenes aprobados". Cuando una prueba falla, lo que lee no es su nombre, sino el mensaje , por ejemplo, la Cadena en la
assert()
que implementa su crítica de éxito. El mensaje debe ser lo suficientemente informativo como para tener una idea de lo que está mal sin leer el cuerpo de la prueba. El nombre no es importante en comparación con eso.fuente
Una forma de saber si eres débil en las pruebas es la trazabilidad. Por lo general, para las pruebas, esto toma la forma de cobertura.
El objetivo es medir qué partes del código son ejercitadas por sus pruebas, para que pueda ver el código que no está cubierto por sus pruebas. Depende de usted (y la herramienta de cobertura) definir qué es una "parte del código". Lo menos es la cobertura de sucursales.
fuente