unitarias unit tipos test pruebas para metodologia las interfaz diseñar desventajas unit-testing tdd mocking

unit testing - tipos - ¿Debo escribir una prueba unitaria para todo?



tipos de pruebas unitarias (13)

Me pregunto si debería escribir prueba unitaria para todo. Hay algunas clases es muy difícil de escribir prueba unitaria. Por ejemplo, estoy escribiendo algún programa para manejar audio. La clase para capturar audio desde el micrófono y clase para reproducir audio a altavoz, ¿cómo puedo escribir la prueba de unidad para esas clases? No puedo obtener la salida y la entrada de esas clases, por lo que es casi imposible probarlas. La única prueba que puedo hacer es getter y setter, esas pruebas aburridas. Entonces, la pregunta es, ¿cuál es la línea guía para escribir la prueba unitaria? ¿Y cómo debo lidiar con estas clases es difícil de probar?


El código que captura y reproduce audio no se puede probar en unidades (aunque puede probar que el método de captura devuelve un error cuando se llama cuando la clase no está vinculada correctamente a un recurso).

Sin embargo, a menos que simplemente escriba el sonido capturado en el disco, el código que invoca sus clases de captura y reproducción puede hacerlo.

Dos consejos:

  • No pruebe el compilador (por ejemplo, getter y setter)
  • Pruebe todo lo que pueda romperse

La respuesta corta es: No, pero eso vale para todo en programación cuando preguntas: "¿Debería IX por todo?"

La respuesta más larga es que al menos deberías considerarlo, lo que estás haciendo. ¿Por qué no puedes burlar la entrada a una clase de grabación de sonido? ¿Por qué no hacer que la clase evite la grabación desde un micrófono para cargar audio de un archivo y hacer que la salida vaya a un archivo en lugar de a un altavoz? La prueba podría comparar el resultado de salida con el resultado correcto conocido.

Para más en el lado filosófico, vea esto .


Otro ejemplo: si desarrolla un motor de juego, quiere probar su sombreado y otras funciones, pero debe confirmarlo visualmente; eso no es nada que un UnitTest clásico pueda decidir.

Su caso: a medida que su aplicación se vuelve más compleja, siempre es doloroso hacer clic en su UI para probar todas sus funciones.

Escribiría un "TestSuite interactivo", donde se muestran varios cuadros de diálogo ficticios (personalizados para cada caso de prueba) con solo las funciones que necesita probar. Una vez que cierre el cuadro de diálogo, se le preguntará si se esperaba el comportamiento. Pero no estoy seguro de si hay soluciones disponibles que podrían ayudar aquí.


Para responder a su pregunta específica, use un cable de bucle invertido. Conecte el parlante al micrófono. Escriba una prueba que se muestre al parlante y que capture del micrófono y verifique que se captó lo mismo que tocó. Mi sugerencia es usar un tono sinusoidal simple para que una FFT pueda decirle si recuperó lo mismo.

La respuesta a la pregunta más general es sí, usted debe probar todo lo que pueda. Hacerlo crea un legado para más adelante, de modo que los cambios en el camino se pueden hacer con tranquilidad. Asegura que su código funcione como se espera. También documenta el uso previsto de las interfaces. Finalmente, fuerza un mejor estilo de codificación. Por lo general, algo que es difícil de probar también está mal diseñado. Escribir para probar significa escribir para un mejor diseño.


Respuesta barata: prueba todo lo que pueda romperse

A fin de cuentas, debe comprender el valor comercial de las pruebas que escribe, no diferente de cualquier otro esfuerzo que realice, cualquier otra base de código que se comprometa a mantener.


Si tiene dificultades para configurar un área particular de código para las pruebas, podría valer la pena investigar un marco burlón como jMock o EasyMock .


Solo escribo pruebas unitarias donde sé que me ahorra tiempo. Cuando comencé las pruebas unitarias, esto fue solo un pequeño porcentaje de las clases Hoy pruebo casi todo y ahorro el tiempo total de desarrollo en cada cosa que hago . Si hubiera una forma eficiente de probar la entrada del usuario a través de un micrófono, yo también lo haría. Pero hasta donde yo sé, no es posible de una manera que me ahorre tiempo.

Por lo tanto, creo que debería probar todo lo que está en su "capacidad de prueba" actual. Debería tratar de aumentar esta capacidad, pero la extralimitación realmente envía señales de prioridades equivocadas; Con toda probabilidad, hay alguna otra prueba que merece más su atención. (Técnicamente estoy infectado con la prueba pero no con TDD )

La ley de rendimientos decrecientes se aplica a las pruebas unitarias tanto como a cualquier otra prueba; su recuperación de la inversión en ese último 5% es muy baja y el costo es alto.


Una regla que uso para decidir si desarrollar pruebas unitarias: si su clase (o cualquier unidad) va a ser lanzada "en la naturaleza", entonces definitivamente debería considerar escribir pruebas unitarias.

Al decir "en la naturaleza", quiero decir: una vez que su código esté en una situación en la que no pueda predecir o controlar cómo las cosas interactuarán con él. Por lo tanto, las clases expuestas a través de una API o las clases expuestas a la entrada del usuario probablemente se someterán a pruebas unitarias.

Personalmente, creo que escribir pruebas unitarias para todo es probable que sea una pérdida de tiempo. Realmente es un problema complejo en el que debes tener en cuenta:

  • ¿Qué tan compleja es la clase? Puede que no valga la pena probar las clases simples.
  • ¿Qué tan crítica es la clase? Se espera que el código que se ejecuta en un cajero automático sea probado en unidades.
  • ¿Cuánto control tienes sobre cómo se usa la clase?

Luego siempre hay:

  • ¿Cuándo es la fecha límite del proyecto?
  • ¿Cuánta energía humana has dedicado a crear pruebas?
  • ¿Sus requisitos son concretos y detallados, o la clase todavía está cambiando con bastante frecuencia?

En cuanto a las clases difíciles, tal vez leer un poco sobre las pruebas de fuzz .


Use la prueba unitaria donde tenga sentido; no apunte a una cobertura del 100%. La directriz principal es pensar en lugar de aplicar dogma o pereza.

Una vez dicho esto: si tienes clases que son naturalmente difíciles de probar, trata de reducir la cantidad que tienen que hacer. Aísle el código no comprobable y separe su API en una interfaz. Luego prueba la lógica que usa esa API contra un simulacro o un apéndice.


Diseñar pruebas es una habilidad adquirida: cuanto más pruebas, mejor lo obtendrás. Algunas cosas parecen difíciles de probar, pero si lo piensas durante unos minutos a menudo puedes encontrar la manera.

Las pruebas pueden ser complicadas, por ejemplo, un programa Java puede iniciar un intérprete o incluso un intérprete de comandos como bash, que a su vez inicia una serie de filtros Unix que esperamos generen archivos binarios idénticos. Sin embargo, no se preocupe: la calidad del código de prueba no tiene que ser tan alta como el código en el producto final.


Pruebo la mayoría de las cosas.

Cada vez que escribo pruebas, también considero que las pruebas son documentación o instrucciones sobre cómo debería usarse mi código, para que yo y otros lo lean en el futuro.

Aunque no pruebo la implementación. Quiero poder cambiar la implementación sin cambiar mis pruebas.

He usado TDD durante quizás uno o dos años, así que tal vez madure y me detenga. Hasta ahora, sin embargo, todavía estoy aprendiendo y creo que no escribo suficientes pruebas.


Tiendo a escribir pruebas tanto como puedo. No solo para demostrar que algo funciona, sino para que sea obvio para otra persona cuando inevitablemente lo rompan más tarde.

He tenido un método de 1 línea de largo. En lugares similares de mi aplicación, he escrito pruebas unitarias, pero teniendo prisa pensé que posiblemente no podría fallar. Estaba equivocado, no funcionó :-)

El beneficio adicional de las pruebas de unidades de escritura no es solo probar su código, sino para que alguien que nunca haya visto su código pueda leer las pruebas y comprender cómo debería funcionar su código en escenarios específicos ... como una especificación.


Es posible que desee consultar mi serie "Probando lo imposible" en mi blog para obtener algunas ideas sobre cómo realizar la prueba.

En su caso, sugiero seguir la idea de Steve Rowe de escribir una prueba que configure el parlante y el micrófono y use un cable de bucle para probar el código de configuración del hardware más la API que permite emitir datos a través del parlante y leer datos de El micrófono.

Esta es una prueba unitaria pero no una automatizada. Moverlo a un conjunto de prueba independiente que no se ejecuta con las otras pruebas automáticas. Si desea automatizarlo, configure una segunda PC con la configuración correcta (más el cable de bucle invertido) y ejecute la prueba de forma remota.

Después de eso, está seguro de que la configuración del hardware funciona, puede enviar y puede recibir audio. Esto le permite probar las clases de procesamiento de datos independientemente del hardware. Usa maquetas para simular el altavoz y el micrófono.