2009-02-05 28 views
20

Me pregunto si debería escribir la 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?¿Debo escribir una prueba unitaria para todo?

Respuesta

36

Utilice las pruebas unitarias donde sea razonable, no apunte a una cobertura del 100%. La directriz principal es piensa en lugar de aplicar dogma o pereza.

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

+1

+1: Simula el hardware con un simulador y úsalo. –

+30

Intenté burlarme de la administración y la empresa. Funcionó bien hasta que el banco comenzó a rebotar mis MockPaychecks.Salí y traté de explicar que manejaba TDD como una fuerza de cambio social, pero llamaron a la seguridad. Banqueros estúpidos. – ddaa

0

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

2

La respuesta corta es: No, pero eso vale para todo en la programación cuando pregunta: "¿Debería X para 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 obtener más información sobre el aspecto filosófico, consulte this.

1

Para responder a su pregunta específica, utilice 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 capturó 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í, debe probar de manera individual 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.

13

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 (¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡espantosos !! Hoy pruebo casi todo y guardo 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 debe probar la unidad 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 prueba infectado pero no TDD infectado)

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

4

Una regla que utilizo para decidir si desarrollar pruebas unitarias: si su clase (o cualquier unidad) va a ser lanzada "al aire libre", entonces definitivamente debería considerar escribir pruebas unitarias.

Por "in the wild", quiero decir: una vez que su código va a estar en una situación en la que no puede 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 las pruebas de unidad de escritura para todo es probable que sea una pérdida de tiempo. Realmente es un problema complejo en el que debe tener en cuenta:

  • ¿Cuán compleja es la clase? Puede que no valga la pena probar las clases simples.
  • ¿Cuán 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 tiene sobre cómo se usa la clase?

Entonces siempre hay:

  • Cuando es la fecha límite del proyecto?
  • ¿Cuánta energía humana has dedicado a crear pruebas?
  • ¿Son sus requisitos 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 fuzz testing.

1

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

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

Escribo 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í.

+0

Bien, mal ejemplo y elección de palabras. Pero no era mi punto, en realidad. –

+0

Para las pruebas de diálogo, consulte mi blog: http://darkviews.wordpress.com/2008/11/11/testing-the-impossible-user-dialogs/ –

1

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 el idea of Steve Rowe para escribir una prueba que configura el altavoz y el micrófono y utilizar un cable de bucle para probar el código de configuración de hardware más la API que permite emitir datos a través del altavoz y leer datos desde el micrófono.

Esta es una prueba de unidad pero no es 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.

+0

¿Podría publicar un enlace a su blog? – finnw

+0

http://darkviews.wordpress.com/tag/tdd/ Hay un par de publicaciones relacionadas bajo las pruebas de etiquetas. –

1

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)
  • prueba todo lo que podría romper
0

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 longitud. 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 unidad 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 su El código debería funcionar en escenarios específicos ... como una especificación.

+1

Parece que el sitio web ha cambiado desde que publiqué esta respuesta. He alterado mi respuesta, gracias por tomarse el tiempo para revisar mis respuestas :) –

1

barato respuesta: Test everything that could possibly break

última instancia sin embargo es necesario entender el valor de negocio de las pruebas que escribe - no es diferente a cualquier otro esfuerzo que gasta, cualquier otra base de código que se comprometa a mantener.

0

Diseñar pruebas es una habilidad adquirida: cuanto más pruebas, mejor te va. 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, p. un programa java puede ejecutar un intérprete o incluso un intérprete de comandos como bash, que a su vez inicia una serie de filtros de 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.

1

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.

Sin embargo, no pruebo la implementación. Quiero poder cambiar la implementación sin cambiar mis pruebas.

He usado TDD por tal vez un año o dos, así que tal vez madure y me detenga. Hasta ahora, sin embargo, todavía estoy aprendiendo y creo que no escribo suficientes pruebas.

Cuestiones relacionadas