domingo, febrero 01, 2009

Iniciando con Test Driven Development (TDD)

Al iniciar con TDD , en algunos proyectos, note que esto ha hecho que cambie mi manera de programar. Ya que al tratar de escribir código de manera que sea testeable, termino escribiendo código mas desacoplado y con mas clases que hacen un trabajo mas especifico y con un poco de dependency injection. también he notado que ahora escribo mucho mas código y el resultado a veces es el mismo que antes (con la desventaja que me tarde mas). Aunque muchas veces los tests me han ayudado a encontrar errores mas rápido y me siento mas seguro de que el código que escribo funciona correctamente.

Por el momento estoy utilizando NUnit y NMock para mis unit test en .Net. Para mi gusto estos frameworks están bien para el tipo de tests que realizo.

Por ejemplo, supongamos que estamos construyendo un registro para usuarios. Y queremos que (cuando un usuario nuevo se registre) se validen los datos del usuario, se inserte a la base de datos y se envié correo de bienvenida.

Al escribir el test para el método de registro, debemos de evitar que este tengan dependencias en otras partes del sistema ya que solo queremos validar que se realicen las reglas de negocio y no tanto como se implementa cada tarea (para cada tarea se realizarán sus propias pruebas unitarias) esto me hace escribir mas clases de tal forma que pueda hacer mock objects para las dependencias.

Entonces en lugar de una sola clase para el registro (RegistrationService) que se encargue de validar, insertar y enviar correo, tendremos varias clases que colaboran para realizar el registro. Como pueden ser: RegistrationService, RegistrationValidator, EmailService y RegistrationDAL. Así podemos probar que el RegistrationService realice la regla de negocio y por separado probar cada una de las tareas. Ademas, si por alguna razón cambia la manera de validar el registro, solo tendríamos que modificar la clase RegistrationValidator y no tenemos que cambiar el resto del proceso de registro. Como ven esto implica realizar mas código, pero se supone que a la larga es mejor, Ahora tenemos código que valida nuestro código.

En mi caso realizar unit tests si me ha ayudado a encontrar errores y a estar seguro de que el código hace lo que tiene que hacer. Aunque debo admitir que hay veces que quisiera no tener que escribir tantas clases y pruebas para cada una de estas clases. En fin todo es cosa de saber que no todo requiere unit test y encontrar el balance entre lo que lo requiere y lo que no.

4 comentarios:

  1. Me ha parecido un artículo realmente interesante y me ha ayudado mucho para empezar a entender mejor este método. También leí otro artículo tuyo llamado "TDD ¿Por qué escribir primero las pruebas?" que fue de gran ayuda al igual que este.

    En mi empresa, una cadena de supermercados internacional, estamos tratando de implantar el TDD (Test Drive Development) como metodología de pruebas.

    Yo soy el responsable del diseño de dicha metodología, pero no se muy bien por donde empezar ya que nunca había oido hablar de ella y lo único que sé es a través de artículos de internet que he podido leer, tan buenos como el tuyo. Yo no soy programador así que he tenido que estudiar bastante todo este mundo de las pruebas para ponerme al día.

    He podido ver que eres un experto en el tema de la metodología TDD, por lo que te estaría enormemente agradecido si me pudierais ayudar con algún tipo de información o consejo que me permitiera empezar a diseñar dicha metodología en mi empresa de forma adecuada, ya que actualmente me encuentro algo desorientado al respecto.

    Muchas gracias por todo.

    Recibe un cordial saludo y mi más sincera enhorabuena por el artículo

    ResponderEliminar
  2. Gracias por tu comentario, actualmente uso el motor de pruebas que viene en VisualStudio 2008 y Moq para los mocks (ya no uso nunit ni NMock), puedes ver una presentación que hice en el grupo local tjnet sobre introducción a TDD. Al inicio son pocas diapositivas y después puro código. espero sea de ayuda.

    ResponderEliminar
  3. Hola Mario,

    ¿Qué tal las navidades? Espero que hayas disfrutado mucho.

    Tu presentación en tjnet está muy bien la verdad, me ha ayudado bastante a comprender mejor esta metodología.

    En estos momentos estoy tratando de adaptar el TDD a mi empresa. En este punto me están surgiendo una serie de dudas más concretas. Tú que dominas estos temas, a ver si me puedes ayudar.

    Te explico cuál sería nuestro ciclo de desarrollo de un proyecto software:

    El primer paso sería determinar las pruebas de aceptación a partir de los requisitos definidos. ¿En este punto se empezarían ya a codificar estas pruebas de aceptación o esperamos a tener el siguiente paso realizado que se explica a continuación? Esta es mi primera duda.

    El segundo paso que hacemos es desglosar cada requisito en tareas. Actualmente sobre cada una de estas tareas se escribe el código necesario y realizamos pruebas. Si ahora queremos aplicar la metodología TDD, primero definiremos las pruebas unitarias, luego con cada prueba se codificará y se realizará el código para que sea correcta la prueba.

    Mi principal duda es en qué orden se realizarían los dos pasos anteriores y cuál es el proceso que deberíamos seguir para pasar de tener las pruebas de aceptación definidas a comprobar que son correctas.

    A nivel de documentación, ¿sería interesante tener registro de todo tipo de pruebas?, ¿cómo y cuáles crees tu que sería mejor documentarlas o no merece la pena guardar registro de ninguna de las pruebas?.

    Por otro lado podrías recomendarme alguna herramienta de software libre para análisis de cobertura de código en la ejecución de pruebas (Java, AS400, VB). ¿Cuál crees tu que sería el porcentaje de cobertura ideal?

    Espero que me aclares un poco todas estas ideas que te planteo.

    Muchas gracias por todo, me eres de gran ayuda.

    Un abrazo

    ResponderEliminar
  4. Gracias por los buenos deseos, espero que te la hayas pasado bien.

    Sobre lo que comentas, pienso que lo mejor para cuando vas iniciando TDD es hacerlo lo mas parecido al proceso actual.
    después el equipo vera que otras practicas se hacen necesarias (por ejemplo usar un IoC container) y no son buenos tantos cambios a la vez ya que podría atrasar bastante los tiempos de entrega.

    Opino que escribas tus pruebas justo antes del código necesario para que estas pasen. en el mismo momento que lo haces actualmente. Así el cambio no sera tan pesado ya de ahí le puedes haciendo ajustes al proceso según las necesidades del equipo.

    Sobre el análisis de cobertura de código, utilizo las herramientas que vienen con VisualStudio no conozco las herramientas para otras plataformas, en lo personal no le doy mucha importancia, TDD es solo el estilo de escribir código. no sustituye a las pruebas que realizan los testers (QA).

    Gracias por tus comentarios,
    Mario

    ResponderEliminar