Está en la página 1de 30

Agosto 2010

Caractersticas de una buena prueba unitaria Beneficios de las pruebas unitarias Pruebas unitarias:
MythBusters Manos a la Obra Cobertura de cdigo Servicios Web Probando el envo de correos electrnicos Orgenes de datos para alimentar las pruebas Interfaz de usuario ASP.NET Capa de acceso a datos Mocks

Deben las pruebas unitarios usar la base de datos? Pex, herramienta automtica para la realizacin de pruebas unitarias en .NET

Test Driven Development, por qu hacer las pruebas antes?

Tienen que poder:

Ejecutar sin necesidad de intervencin manual


Repetirse tantas veces como uno quiera Cubrir casi la totalidad del cdigo Ejecutarse independientemente del estado del entorno Ejecutarse sin afectar la ejecucin de otra

Las diferentes relaciones que puedan existir entre los mdulos deben ser simulada para evitar dependencias entre mdulos (stubs o mocks) Es importante conocer claramente cul es el objetivo del test

Es importante tener en cuenta:

No siempre ser posible ni necesario cumplir con todas estas reglas y ser la experiencia la que nos guiar en la realizacin de las mismas

La vida del desarrollador ser mucho ms fcil Las pruebas fomentan el cambio y la refactorizacin Se reducen drsticamente los problemas y tiempos dedicados a la integracin Nos ayudan a entender mejor el cdigo

Nos permite poder probar o depurar un mdulo sin necesidad de disponer del sistema completo.

Si son tan buenas: por qu no se usan?


Desconocimiento en la materia Poca tradicin Falsos Mitos

Mito: Creer que escribir pruebas unitarias es escribir el doble de cdigo


Las pruebas siempre se deben ir escribiendo a medida que se desarrolla el software La realizacin de pruebas unitarias debe ser un proceso obligatorio en nuestros desarrollos y no deben quedar a voluntad del desarrollador Si no ests familiarizado con el uso de pruebas unitarias la perseverancia debe ser tu gran aliado

Dejar la implementacin de pruebas para el final no es realista.

Y si no escribiramos este cdigo cmo probamos?


Hay diferentes situaciones:
No se prueba
Los tiempos de integracin, depuracin y correccin de incidencias se multiplican.

Uso de aplicaciones de pruebas de usar y tirar


La situacin no es la ideal pero realmente el desarrollo de pruebas unitarias puede tener una semejanza con este tipo de aplicaciones

Mito: Desarrollar pruebas unitarias hace que los tiempos de desarrollo se incrementen, incrementando los costes del proyecto.
Desarrollar con pruebas unitarias y desarrollar probando con mtodos ms rsticos, esta segunda es ms lenta y por tanto, ms cara.

La manera ms rpida de desarrollar software es desarrollarlo bien.


La prdida de confianza del cliente. Muchos productos tienen un mantenimiento evolutivo que implica el desarrollo de nuevas funcionalidades y la correccin de incidencias. Sin un proceso adecuado de pruebas unitarias, los tiempos de pruebas se dispararn en fases posteriores.

Visual Studio proporciona un sistema sencillo para poder crear nuestras pruebas unitarias. Recomendacin: Crear al menos un proyecto de Test por cada proyecto que tenga la aplicacin.
Supondremos una clase que tiene el mtodo Suma Referencia: Microsoft.VisualStudio.QualityTools.UnitTestFramework Atributo TestMethod

Crea dos nuevos archivos:


Sample.vsmdi: Permite acceder al editor de las lista de pruebas unitarias LocalTestRun.testrnconfig Permite configurar algunos aspectos relacionados con la ejecucin de las pruebas. (Anlisis de Cobertura)

Clase Assert

Aunque seguramente usaremos algunos de los mtodos de la clase Assert en la mayora de las situaciones no es de uso obligatorio. Con este atributo estamos especificando que el resultado esperado de la ejecucin de la prueba es la excepcin ArgumentException. Atributo ClassInitialize Atributo TestInitialize Atributo ClassCleanup Atributo TestCleanup

Atributo ExpectedException

Mtodos de inicializacin

Es un factor clave para determinar cmo de bueno son nuestras pruebas unitarias Nos dice la cantidad de cdigo que est sometido a nuestras pruebas Una cobertura del 85-90% indica que la gran mayora de nuestro cdigo est siendo probado. Visual Studio slo medir la cobertura en aquellos ensamblados que seleccionemos.
Archivo LocalTestRun.testrunconfig

La cobertura de cdigo nos proporciona informacin de suma relevancia a la hora de saber que porciones de nuestro cdigo carecen en absoluto de pruebas y, en consecuencia, ilumina aquellos lugares donde debemos centrar nuestros esfuerzos. Existen otros escenarios, menos conocidos, en los que observar la cobertura de cdigo nos puede ayudar de manera significativa:
Cuando se ejecutan pruebas manuales
La cobertura de cdigo nos proporciona informacin sobre el cdigo de nuestra aplicacin se ha ejecutado, lo que muchas veces obviamos es que esa ejecucin no tiene que estar provocada por la ejecucin de pruebas unitarias. Qu parte de cdigo se utilizan en cada escenario?Qu partes del cdigo no son ejercitadas por las pruebas?Qu partes del cdigo son ejecutadas por ms de una prueba?Cubrimos mediante pruebas manuales aquellas partes del cdigo no probadas por las pruebas unitarias?
Cuntas veces no os hemos enfrentado a un error y a pesar de poderle reproducir hemos tenido problemas para saber en que parte del cdigo se produca?

Cuando estamos depurando un error

Los clientes reales no acceden al Servicio Web como una clase normal, sino que acceden a ella a travs de una clase proxy (Add Web Reference o Add Service Reference) Al menos una de las pruebas que implementaremos sobre el Servicio Web debe simular ser un cliente real y hacer las llamadas a travs de una clase proxy Necesitaremos que el servicio se arranque cada vez que lanzamos la prueba
Atributo AspNetDevelopmentServer Mtodo TryUrlRedirection

Nuestro objetivo ser asegurarnos que cuando llamamos a este mtodo se genera un mensaje de correo. El framework nos posibilita que podamos configurar el sistema de mensajera para que en lugar de usar un servidor SMTP para enviar correos, simplemente stos se dejen en el disco, en un directorio. Vamos a utilizar lo mtodos de inicializacin para asegurarnos de que el entorno est como necesitamos antes de lanzar la prueba y que lo dejamos limpio despus de finalizar la ejecucin de las mismas

Cuando las N pruebas slo cambian en los datos de entrada, Visual Studio nos ofrece generar una nica prueba y cargar los diferentes escenarios de datos desde un origen de datos.
Atributo DataSource: indica el origen de datos que se emplear en la prueba, as como la forma de acceder al mismo Atributo DeployementItem permite especificar archivos adicionales que se incluirn entre los archivos que se usarn para la prueba

Probar el 100% de la funcionalidad de la interfaz de usuario de manera automatizada es complicado con las herramientas que disponemos
En este tipo de prueba se sigue un enfoque de pruebas de cobertura

Visual Studio nos permite grabar secuencias completas contra la interfaz de usuario, con el objetivo de poder repetirlas tantas veces como queremos Cuando se inicia la prueba debe arrancar la aplicacin ASP.NET para que la prueba pueda realizarse
Atributo UrlToTest Atributo AspNetDevelopmentServerHost

Podemos hacer pruebas unitarias sobre la capa de acceso a datos, tanto del cdigo .NET como de los procedimientos almacenados Para poder realizar pruebas unitarias de los procedimientos almacenados es necesario disponer y conocer Visual Studio Database Edition. Visual Studio nos permite versionar el schema de base de datos como cualquier otro proyecto, permitiendo que todos los desarrolladores del equipo puedan disponer de la ltima versin de la base de datos en cualquier momento. Se implementa una prueba unitaria por cada mtodo de acceso a datos y por cada procedimiento almacenado. Y como mnimo, en las pruebas busco cobertura, es decir, que todos los procedimientos estn probados y que se pruebe el 100% del contenido de los mismos

Nos estaremos protegiendo contra sentencias mal construidas, sentencias SQL que no devuelven todos los campos que se esperan, errores en el nmero de parmetros que se pasan a los procedimientos, cambios en la base de datos que hacen que dejen de funcionar algunas sentencias SQL, etc. Se pueden crear planes de generacin de datos para cargar las tablas de la base de datos con datos de ejemplo y as hacer que nuestras pruebas sean algo ms reales
Agregar >Plan de Generacin de Datos

Los mocks son objetos falsos que simulan el comportamiento de un objeto real. El concepto del mock es sencillo: si tanto el objeto real como el objeto false implementan la misma interfaz y el mdulo que estamos probando trabaja contra interfaces en lugar de contra objetos, podremos hacer uso indistintamente de objeto falso o del objeto real sin que esto afecte al mdulo, siempre y cuando ambos objetos tengan el mismo comportamiento Al menos deberamos usar mocks en los casos de dependencias externas con otros equipos de desarrollo o con mdulos con los que tengamos que integrarnos. Existen varios framework, como RhinoMock o Nmock, que nos van a permitir generar los objetos falsos, no debemos olvidar que cualquier objeto falso que creemos puede considerarse un mock, aunque no se haga uso de un framwork.

La respuesta acadmica es NO.


Las pruebas deben poderse correr en cualquier entorno, sin dependencias ms que del propio framework de testeo elegido. Para lograr niveles de cobertura adecuado debemos recurrir al uso de objetos mock.

Esto trata sobre la conveniencia o no de que nuestras pruebas unitarias de las capas de acceso a datos y de lgica de negocio se ejecuten con una conexin a una base de datos real establecida y con un juego de datos de prueba.

Recomendacin:

En sistemas guiados por datos, donde el almacenamiento de datos es una cuestin central, las pruebas unitarias debe utilizar la base de datos.
A menudo es necesario realizar refactorizaciones o cambios en la base de datos que son muy susceptibles de producir regresiones, introducir problemas de rendimiento o impactar en partes inesperadas de nuestro software. Qu mejor manera de probar el comportamiento de nuestra base de datos frente a bloqueos y su rendimiento que tener varios desarrolladores corriendo a menudo test que ejercitan el acceso a datos de manera concurrente?

Que nuestras pruebas unitarias tiren de la base de datos, nos proporciona la ventaja de poder hacer cambios en nuestro esquema de datos con la confianza de que detectaremos los errores que estos cambios puedan introducir

Problemas a abordar:
Tenemos que garantizar que las pruebas en cualquier caso, se ejecuten o no de manera satisfactoria, dejarn la base de datos en el estado inicial Todos los desarrolladores debern disponer de una versin actualizada de la base de datos de manera que puedan correr las pruebas siempre contra la versin de la base de datos ms actualizada.

Una mxima de las pruebas unitarias dice que las pruebas deben ser rpidos en su ejecucin, pues sino deja de correr a menudo y pierden su utilidad.

Pex (Program Exploration).


El desarrollador escribe un conjunto de pruebas similares a pruebas unitarias pero que toman parmetros. Luego utilizaremos Pex (que est integrado con Visual Studio 2010) para generar pruebas unitarias y ejecutarlas

Tiene la capacidad de explorar nuestro cdigo, encontrar el grafo de caminos del algoritmo, seleccionar el subconjunto mnimo suficiente de caminos para probar todas las sentencias de nuestro cdigo y, finalmente, generar las entradas representativas necesarias al programa para recorrer todos estos caminos.

La propia definicin especfica de TDD, dice que las pruebas se han de escribir siempre antes que el cdigo.

En realidad existen dos aproximaciones Test at First (Test al Principio) y Test at Last (Test al Final) Algunos utilizan un enfoque mixto, aunque ms sesgado hacia escribir antes las pruebas. Las pruebas dan la funcionalidad La prueba da el diseo del mtodo (entrada, salida, que tiene que pasar en medio) K.I.S.S. (Keep it simple stupid), el cdigo que se haga totalmente dirigido a solucionar la prueba, para futuras situaciones, casusticas, tendr ms pruebas. Se consigue una mayor cobertura de cdigo

Ventajas de hacer las pruebas al principio:

WebCast:
Desarrollo conducido por pruebas. TDD - De los conceptos a la prctica

http://geeks.ms/blogs/oberroteran