unitarias tipos software pruebas las ist ejemplo desventajas unit-testing testing

unit testing - tipos - ¿Nuevo en pruebas de unidad, cómo escribir grandes pruebas?



pruebas unitarias python (8)

Mis pruebas parecen estar tan estrechamente relacionadas con el método (probando todo el código de ruta, esperando que algunos métodos internos se llamen varias veces, con ciertos argumentos), que parece que si alguna vez refactorizo ​​el método, las pruebas fallarán incluso si El comportamiento final del método no cambió.

Creo que lo estás haciendo mal.

Una prueba unitaria debe:

  • prueba un método
  • proporcionar algunos argumentos específicos a ese método
  • prueba de que el resultado es el esperado

No debe mirar dentro del método para ver lo que está haciendo, por lo que cambiar las partes internas no debe hacer que la prueba falle. No debe probar directamente que se están llamando métodos privados. Si está interesado en saber si su código privado está siendo probado, use una herramienta de cobertura de código. Pero no se obsesione con esto: la cobertura del 100% no es un requisito.

Si su método llama a métodos públicos en otras clases, y estas llamadas están garantizadas por su interfaz, entonces puede probar que estas llamadas se realizan utilizando un marco de burla.

No debe utilizar el método en sí (o cualquiera de los códigos internos que utiliza) para generar el resultado esperado de forma dinámica. El resultado esperado debe estar codificado en su caso de prueba para que no cambie cuando cambie la implementación. Aquí hay un ejemplo simplificado de lo que debería hacer una prueba de unidad:

testAdd() { int x = 5; int y = -2; int expectedResult = 3; Calculator calculator = new Calculator(); int actualResult = calculator.Add(x, y); Assert.AreEqual(expectedResult, actualResult); }

Tenga en cuenta que la forma en que se calcula el resultado no se verifica, solo que el resultado es correcto. Continúe agregando más y más casos de prueba simples como el anterior hasta que haya cubierto tantos escenarios como sea posible. Usa la herramienta de cobertura de código para ver si te has perdido algún camino interesante.

Soy bastante nuevo en el mundo de pruebas de unidad, y decidí agregar cobertura de prueba para mi aplicación existente esta semana.

Esta es una tarea enorme, principalmente debido a la cantidad de clases que se deben probar, pero también porque escribir exámenes es algo nuevo para mí.

Ya he escrito exámenes para un montón de clases, pero ahora me pregunto si lo estoy haciendo bien.

Cuando estoy escribiendo pruebas para un método, tengo la sensación de volver a escribir por segunda vez lo que ya escribí en el método en sí.
Mis pruebas parecen estar tan estrechamente relacionadas con el método (probando todo el código de ruta, esperando que algunos métodos internos se llamen varias veces, con ciertos argumentos), que parece que si alguna vez refactorizo ​​el método, las pruebas fallarán incluso si El comportamiento final del método no cambió.

Esto es solo un sentimiento, y como dije anteriormente, no tengo experiencia en pruebas. Si algunos evaluadores más experimentados pudieran darme consejos sobre cómo escribir excelentes pruebas para una aplicación existente, eso sería muy apreciado.

Edit: Me gustaría agradecerle a Stack Overflow, tuve excelentes entradas en menos de 15 minutos que respondieron más de las horas de lectura en línea que acabo de hacer.


Este es el mejor libro para pruebas de unidad: manning.com/osherove

Explica todas las mejores prácticas, lo que se debe hacer y lo que no se debe hacer para las pruebas unitarias.


Intente escribir una prueba de unidad antes de escribir el método que va a probar.

Eso definitivamente te obligará a pensar un poco diferente acerca de cómo se están haciendo las cosas. No tendrá idea de cómo va a funcionar el método, solo lo que se supone que debe hacer.

Siempre debe probar los resultados del método, no cómo el método obtiene esos resultados.


La prueba de unidad se trata de la salida que obtiene de una función / método / aplicación. No importa en absoluto cómo se produce el resultado, solo importa que sea correcto. Por lo tanto, su enfoque de contar llamadas a métodos internos y eso es incorrecto. Lo que tiendo a hacer es sentarme y escribir lo que un método debe devolver, dados ciertos valores de entrada o cierto entorno, luego escribir una prueba que compare el valor real devuelto con lo que se me ocurrió.


No escriba pruebas para obtener una cobertura completa de su código. Escribe pruebas que garanticen tus requerimientos. Puedes descubrir codepaths que son innecesarios. A la inversa, si son necesarios, están ahí para cumplir algún tipo de requisito; Encuéntrelo como es y pruebe el requisito (no el camino).

Mantenga sus pruebas pequeñas: una prueba por requerimiento.

Más tarde, cuando necesite hacer un cambio (o escribir un nuevo código), intente escribir una prueba primero. Solo uno. Entonces habrás dado el primer paso en el desarrollo guiado por pruebas.


Para las pruebas unitarias, encontré que Test Driven (pruebas primero, código segundo) y código primero, prueba segundo es extremadamente útil.

En lugar de escribir código, luego escribir prueba. Escriba el código y luego mire lo que PIENSE que debería estar haciendo el código. Piense en todos los usos previstos y luego escriba una prueba para cada uno. Encuentro que las pruebas de escritura son más rápidas pero más complicadas que la codificación en sí misma. Las pruebas deben probar la intención. También pensando en las intenciones que terminan encontrando casos de esquina en la fase de escritura de prueba. Y, por supuesto, al escribir pruebas, es posible que uno de los pocos usos cause un error (algo que a menudo encuentro, y estoy muy contento de que este error no corrompiera los datos y quedara sin marcar).

Sin embargo, las pruebas son casi como codificar dos veces. De hecho, tenía aplicaciones donde había más código de prueba (cantidad) que código de aplicación. Un ejemplo fue una máquina de estados muy compleja. Tenía que asegurarme de que, después de agregarle más lógica, todo funcionara en todos los casos de uso anteriores. Y dado que esos casos eran bastante difíciles de seguir al mirar el código, terminé teniendo un conjunto de pruebas tan bueno para esta máquina que estaba seguro de que no se rompería incluso después de hacer cambios, y las pruebas me salvaron el culo varias veces . Y a medida que los usuarios o probadores encontraban errores con los casos de flujos o esquinas sin resolver, adivinen qué, agregados a las pruebas y nunca volvían a suceder. Esto realmente dio a los usuarios confianza en mi trabajo además de hacer que todo fuera súper estable. Y cuando tuvo que ser reescrito por razones de rendimiento, adivine qué, funcionó como se esperaba en todas las entradas gracias a las pruebas.

Todos los ejemplos simples como function square(number) son excelentes y todos, y probablemente sean malos candidatos para pasar mucho tiempo probando. Los que hacen lógica empresarial importante, ahí es donde las pruebas son importantes. Prueba los requisitos. No se limite a probar la plomería. Si los requisitos cambian, entonces adivina qué, las pruebas también deben hacerlo.

Las pruebas no deberían estar literalmente probando esa función foo invocado la barra de funciones 3 veces. Eso está mal. Compruebe si el resultado y los efectos secundarios son correctos, no la mecánica interna.


Se supone que las pruebas mejoran la mantenibilidad. Si cambia un método y se rompe una prueba, eso puede ser bueno. Por otro lado, si consideras tu método como una caja negra, no debería importar lo que esté dentro del método. El hecho es que necesitas burlarte de las cosas para algunas pruebas, y en esos casos realmente no puedes tratar el método como una caja negra. Lo único que puede hacer es realizar una prueba de integración: carga una instancia del servicio a prueba con una instancia completa y pídale que haga su trabajo como si se ejecutara en su aplicación. Entonces puedes tratarlo como una caja negra.

When I''m writing tests for a method, I have the feeling of rewriting a second time what I already wrote in the method itself. My tests just seems so tightly bound to the method (testing all codepath, expecting some inner methods to be called a number of times, with certain arguments), that it seems that if I ever refactor the method, the tests will fail even if the final behavior of the method did not change.

Esto se debe a que está escribiendo sus pruebas después de escribir su código. Si lo hicieras al revés (escribiste las pruebas primero) no se sentiría de esta manera.


Vale la pena señalar que las pruebas unitarias de adaptación en el código existente son mucho más difíciles que conducir la creación de ese código con las pruebas en primer lugar. Esa es una de las grandes preguntas al tratar con aplicaciones heredadas ... ¿cómo realizar pruebas de unidad? Esto se ha preguntado muchas veces antes (por lo que puede estar cerrado como una pregunta engañosa), y la gente generalmente termina aquí:

Mover el código existente a Test Driven Development

Respaldo la recomendación del libro de la respuesta aceptada, pero más allá de eso hay más información vinculada en las respuestas allí.