Si bien hay formas de evitar que se ejecuten las pruebas unitarias, ¿cuál es el valor de verificar las pruebas unitarias que fallan?
Usaré un ejemplo simple: mayúsculas y minúsculas. El código actual distingue entre mayúsculas y minúsculas. Una entrada válida en el método es "Cat" y devolvería una enumeración de Animal.Cat. Sin embargo, la funcionalidad deseada del método no debe ser sensible a mayúsculas y minúsculas. Entonces, si el método descrito se pasó "gato", posiblemente podría devolver algo como Animal.Null en lugar de Animal.Cat y la prueba unitaria fallaría. Aunque un simple cambio de código haría que esto funcionara, solucionar un problema más complejo puede llevar semanas, pero identificar el error con una prueba unitaria podría ser una tarea menos compleja.
La aplicación que se está analizando actualmente tiene 4 años de código que "funciona". Sin embargo, las discusiones recientes sobre las pruebas unitarias han encontrado fallas en el código. Algunos solo necesitan documentación de implementación explícita (por ejemplo, mayúsculas o minúsculas) o código que no ejecute el error en función de cómo se llama actualmente. Pero se pueden crear pruebas unitarias ejecutando escenarios específicos que harán que se vea el error y sean entradas válidas.
¿Cuál es el valor de verificar las pruebas unitarias que ejercitan el error hasta que alguien pueda solucionar el código?
¿Debería marcarse esta prueba unitaria con ignorar, prioridad, categoría, etc., para determinar si una compilación fue exitosa en base a las pruebas ejecutadas? Finalmente, la prueba unitaria debe crearse para ejecutar el código una vez que alguien lo arregle.
Por un lado, muestra que los errores identificados no se han corregido. Por otro lado, podría haber cientos de pruebas unitarias fallidas que aparecen en los registros y eliminar las que deberían fallar frente a las fallas debido a un registro de código sería difícil de encontrar.
fuente
Respuestas:
No me gustan las pruebas de unidades rotas registradas porque producen ruido innecesario. Después de cada prueba de unidad, tendría que verificar todos los problemas fallidos (rojo). ¿Es rojo porque hay un nuevo problema o porque hay un viejo abierto para hacer / arreglar? Esto no está bien si hay más de 20 pruebas unitarias.
En cambio uso
[Ignore("Reason")]
atributo que hace que el resultado sea amarillo othrow new NotImplementedException()
eso hace que el resultado sea grisNota: Estoy usando NUnit para .net. No estoy seguro de si la función "gris" está presente en otros marcos de prueba de unidad.
Entonces me gusta el siguiente significado de resultados de pruebas unitarias.
Todo excepto "rojo" puede registrarse.
Para responder a la pregunta: hay más daño que valor al registrar "test-fallas rojas", pero la comprobación de "pruebas ignoradas amarillas" o "pruebas-NotImplemented-grises" puede ser útil como lista de tareas pendientes.
fuente
will probably never be fixed
es una decisión política si quiere gastar efford en pruebas automatizadas o no. Con las "pruebas ignoradas" tienes la oportunidad de arreglarlas. Tirar "pruebas ignoradas" significa "abandonar las pruebas automatizadas poco a poco hasta que no haya más"No voy a fingir que este es el estándar de la industria, pero reviso las pruebas interrumpidas como una forma de recordarme a mí oa mis otros miembros del proyecto que todavía hay un problema con el código o la prueba de la unidad en sí.
Supongo que una cosa a considerar es si sus políticas de desarrollo permiten pruebas fallidas sin penalización. Tengo un amigo que trabaja en una tienda que realiza un desarrollo basado en pruebas, por lo que siempre comienzan con pruebas fallidas ...
fuente
Las pruebas unitarias que fallan le dan al equipo de desarrollo visibilidad sobre lo que debe hacerse para cumplir con las especificaciones acordadas.
En resumen, las pruebas de unidades que fallan le dan al equipo una lista de "TODO".
Por esta razón, las pruebas unitarias fallidas son mucho mejores que ninguna prueba unitaria. *
La ausencia de pruebas unitarias deja al equipo de desarrollo en la oscuridad; Las especificaciones deben confirmarse repetidamente manualmente .
[* Siempre que las pruebas unitarias realmente prueben algo útil.]
fuente
El propósito de las pruebas unitarias es afirmar el comportamiento esperado de un sistema, no documentar defectos. Si usamos pruebas unitarias para documentar defectos, entonces se reduce su utilidad para afirmar el comportamiento esperado. La respuesta a la pregunta "¿Por qué falló esta prueba?" No es un simple "Oh, algo está roto que no esperaba estar roto". Se desconoce si la falla de la prueba es esperada o inesperada.
Aquí hay un párrafo del comienzo del capítulo 13 de Trabajo efectivo con código heredado :
fuente
Pero los rotos que identifican errores en un nuevo proyecto, nombrado como tal. De esa manera, puede ver que DEBEN romperse ... A medida que se reparan, se volverán verdes y se trasladarán al conjunto de pruebas normal.
NOTA: Ese proyecto tendría que configurarse para que no se construya en el servidor de compilación, si su servidor de compilación evita los registros que rompen la compilación (suponiendo que defina una compilación interrumpida como una en la que no pasan todas las pruebas)
fuente
Las pruebas unitarias deben probar los casos de error además de los casos de éxito de una función. Una función debe rechazar explícitamente la entrada incorrecta o debe tener documentación para explicar qué entrada se considera válida.
Si tiene una función que no está haciendo ninguna de esas cosas, es un error y debe tener una forma de registrar que existe. Crear una prueba unitaria que demuestre este problema es una forma de hacerlo. Presentar un ticket de error es otra opción.
El punto de las pruebas unitarias no es tener el 100% de éxito, el punto es encontrar y corregir errores en el código. No realizar pruebas es una manera fácil de tener el 100% de éxito, pero eso no es muy beneficioso para el proyecto.
fuente
Presente un error por cada falla y observe eso en el resultado de la prueba. Luego, si alguna vez actúas y corriges el error, tu prueba pasa y la eliminas del resultado de la prueba. Nunca ignores los problemas.
fuente
La forma en que veo que se hace TDD con la implementación de pruebas para un código inacabado es escribir primero las pruebas con el atributo [ExpectedException] o similar. Esto debería pasar inicialmente ya que el código incompleto no tendría ninguna lógica y escribiría un nuevo código de excepción (). Aunque pasar la excepción es incorrecto, al menos esto haría que las pruebas pasen inicialmente y que sean aptas para el registro. Podemos olvidar una prueba ignorada pero definitivamente podemos ordenar o completar el código incompleto. Cuando lo hagamos, automáticamente comenzará a fallar automáticamente la prueba correspondiente que esperaba una excpección y le alarmaría para que la arregle. Esto puede implicar una ligera alteración de la prueba para deshacerse de ExpectException y, en su lugar, hacer afirmaciones reales. ¿CI, Dev, evaluadores y clientes, todos contentos y en una situación en la que todos ganan?
fuente