2010-08-11 7 views
5

Parece que cada ejemplo de prueba de unidad que he encontrado es increíblemente obvio y está enlatado. Cosas como afirmar que x + 3 == 8, y otras cosas. Simplemente me cuesta ver cómo probaría unidades del mundo real, como las consultas SQL, o si un regEx utilizado para la validación de formularios funciona correctamente.Pruebas unitarias: no se puede pasar de la teoría a la práctica

Ejemplo práctico: estoy trabajando en dos sitios ASP.NET MVC 2 que son impulsados ​​por DB. Tengo una solución de unidad de prueba para cada uno de ellos, pero no tengo idea de qué tipo de pruebas serían útiles. La mayor parte del trabajo que el sitio hará es escribir datos o recuperar y organizar los datos del DB. ¿Simplemente probaría que las diversas consultas tuvieron éxito al acceder al DB? ¿Cómo probaría la corrección (p. Ej., Escribir datos en los campos correctos o corregir los datos que se recuperan)?

Solo estoy pasando un momento difícil para transformar mi propia manera informal de probar y depurar en el tipo de prueba assert (x) más formalizado.

Respuesta

2

Primero, pregúntese "¿Por qué las pruebas unitarias son difíciles de escribir para mi código real?" Quizás la respuesta es que su código real está haciendo demasiado. Si tiene un único módulo de código lleno de declaraciones "nuevas" y declaraciones "if" y declaraciones "switch" y declaraciones matemáticas inteligentes y acceso a la base de datos, va a ser doloroso escribir una prueba, y mucho menos probar adecuadamente la lógica y el mates. Pero si sacaste las declaraciones "nuevas" en un método de fábrica, podrías obtener fácilmente objetos falsos para probar.Si sacó las cláusulas "si" y "cambia" las declaraciones en patrones de máquina de estado, no tendría tantas combinaciones para probar. Si elimina el acceso a la base de datos a un objeto proveedor de datos externo, puede proporcionar datos de prueba simples para ejecutar sus instrucciones matemáticas. Ahora está probando la creación de objetos, las transiciones de estado y el acceso a los datos, todo por separado de sus ingeniosas afirmaciones matemáticas. Todos estos pasos se simplificaron simplificándolos.

Un código de razón clave es difícil de probar, ya que contiene "dependencias internas", como las dependencias que crea o las dependencias de las bibliotecas. Si su código dice "Foo theFoo = new Foo();" no puedes sustituir fácilmente un MockFoo para probarlo. Pero si su constructor o método solicita que se transfiera el FOO en lugar de construirse a sí mismo, su arnés de prueba puede pasar fácilmente en un MockFoo.

Cuando escribe código, pregúntese "¿cómo puedo escribir una prueba de unidad para este código?" Si la respuesta es "es difícil", puede considerar modificar su código para que sea más fácil realizar la prueba. Lo que hace es hacer que su unidad pruebe el primer consumidor real de su código: está probando la interfaz de su código al escribir la prueba.

Al modificar sus interfaces para hacerlas más fáciles de probar, se encontrará mejor adhiriéndose a los principios orientados a objetos de "cohesión ajustada" y "acoplamiento libre".

La prueba de la unidad no se trata solo de las pruebas. Las pruebas de unidad de escritura realmente mejoran sus diseños. Avanza un poco más en el camino y terminarás con el desarrollo impulsado por prueba.

¡Buena suerte!

6

Para que las pruebas unitarias sean factibles, su código deberá aplicarse a los principios de cohesión y desacoplamiento. De hecho, forzará esos principios en su código a medida que lo aplique. Es decir, si su código no está bien factorizado (es decir, los principios de diseño de OO aplicados correctamente), las pruebas unitarias serán casi imposibles y/o inútiles.

Probablemente, la mejor manera de pensar en esto sería '¿Cómo puedo dividir todo el trabajo de mi aplicación en piezas de código más pequeñas y cohesivas que solo hacen una o dos cosas y usarlas para armarlas? ¿mi aplicación?'

Hasta que haya internalizado esta forma de pensar en términos de cómo piensa acerca de su código, las pruebas unitarias probablemente no tengan sentido.

+4

En realidad, es un poco de pollo y huevo. No puede escribir buenas pruebas unitarias sin un código bien diseñado (comprobable). No se puede diseñar bien el código (comprobable) sin haber probado una prueba de unidad. –

+0

+1, especialmente para 'forzar esos principios en su código'. De hecho, una vez leí un artículo que sugería que la escritura de código para que sea fácilmente comprobable por la unidad reducía las tasas de errores más que implementar las pruebas. El hecho de factorizar su código en unidades fácilmente comprobables hace que la corrección sea más obvia y reduce la posibilidad de errores. Pensar cómo va a probar algún código hace que lo escriba en una forma más modular. Ciertamente lo he notado en mi código. De repente, la imitación y la inyección de dependencia caen en su lugar. –

2

Bueno, si x + 3 == 8 no es suficiente de una pista, ¿qué pasa con x==y?

Dicho de otra manera, lo que está probando es el comportamiento correcto e incorrecto de los tipos o funciones, no solo cuando se usa con condiciones normales, sino también bajo condiciones inesperadas. Con una clase, por ejemplo, necesitas reconocer que solo crear instancias no es suficiente. ¿Se cumplen los requisitos previos de la clase? ¿Y las postcondiciones? ¿Qué debería pasar cuando no se cumplen? Aquí es donde establece los límites entre usted y la persona que usa la clase (también podría ser usted, por supuesto) para diferenciar entre un error en la clase o un error en el uso de la clase por parte del usuario. ¿Las instancias de su clase cambian de estado cuando se usan con patrones de codificación particulares? Si es así, ¿cómo es eso? Si no, ¿por qué no ?, y (idealmente) en todas las condiciones de uso posibles; es este comportamiento correcto?
Las pruebas unitarias también son un buen lugar para que un usuario de una clase (por ejemplo) vea cómo se espera que se use la clase, cómo evitar su uso y qué podría suceder bajo circunstancias excepcionales (donde si algo sale mal, se supone que su clase reacciona de alguna manera particular en lugar de simplemente romperse). Algo así como la documentación incorporada para el desarrollador.

1

Tal vez aprender de un ejemplo sería más útil para usted. Puede echar un vistazo al NerdDinner sample app y ver qué tipo de pruebas hace. También puede consultar el MVC source code y ver cómo se prueba.

Cuestiones relacionadas