Escolar Documentos
Profissional Documentos
Cultura Documentos
Integrantes:
Ibaez, Rodrigo Sebastin Keimel, Marina Gisele Lizarralde, Ignacio Luna, Julia Elizabeth Tommasel, Antonela Vega, Maria Florencia Villavicencio, Christian Paulo
Tabla de contenido
Introduccin ...................................................................................................................................................... 2 Test-Driven Development ................................................................................................................................. 3 El ciclo de desarrollo TDD .................................................................................................................................. 4 Usando TDD: Caractersticas Importantes ........................................................................................................ 6 Deficiencias .................................................................................................................................................... 6 Beneficios ...................................................................................................................................................... 6 Diferencias entre TDD y otros modelos............................................................................................................. 8 Modelos de desarrollo de software evolutivos y TDD .................................................................................. 9 El ciclo TDD: Un pequeo ejemplo .................................................................................................................. 11 Perfeccionando el uso de TDD ........................................................................................................................ 14 TDD y Diseo ............................................................................................................................................... 14 Reusabilidad, Patrones de Diseo y TDD..................................................................................................... 14 Buenas prcticas al momento del desarrollo de los Tests .......................................................................... 14 Patrones de Testing Generales .................................................................................................................... 15 Patrones de Test Rojo.................................................................................................................................. 16 Patrones de Test Verde ............................................................................................................................... 17 Herramientas ................................................................................................................................................... 19 Familia xUnit ................................................................................................................................................ 19 Caractersticas comunes de la familia ......................................................................................................... 19 JUnit ............................................................................................................................................................. 20 Ejemplo de utilizacin de JUnit ............................................................................................................... 20 Boost ............................................................................................................................................................ 21 Utilizacin ................................................................................................................................................ 22 NUnit............................................................................................................................................................ 22 Funcionamiento ....................................................................................................................................... 23 Atributos .................................................................................................................................................. 23 Aserciones ............................................................................................................................................... 24 Adoptando TDD ............................................................................................................................................... 26 Fallas en la utilizacin de TDD ..................................................................................................................... 26 Conclusiones .................................................................................................................................................... 28 Bibliografa ....................................................................................................................................................... 29
Introduccin
La evolucin de los mtodos giles comenz a mediados de los 90. Antes a esto, el software era desarrollado centrndose en la planificacin del proyecto, un cuidadoso diseo y una extensa documentacin, lo que produca un importante overhead en proyectos no muy grandes. En mtodos giles dos de cada cuatro semanas son utilizadas como iteraciones. El objetivo de cada una de ellas es ofrecer software funcional, lo cual implica una planificacin cuidadosa, anlisis, diseo, implementacin y testing individuales. Especificar las entradas y salidas antes de programar la aplicacin concreta no es algo nuevo en el desarrollo de software, y TDD se basa en sta idea.
Test-Driven Development
[AEK09] [GEO02] [GEO03b] [WIL03] TDD es una prctica emergente que tiene su origen en Extreme Programming (XP), y que procura producir software de alta calidad rpidamente, sin desatender los cambios inevitables en los requerimientos y el diseo. Este mtodo de desarrollo de software se utiliza generalmente en procesos giles. Anteriormente, TDD fue llamado test-fist programming en comparacin a los mtodos de desarrollo tradicionales, en los cuales los tests se realizan luego de la implementacin del sistema. El problema con ese enfoque tradicional (llamado test-last programming) radica en que el cdigo no est preparado para ser testeado al trmino de su codificacin, incluso en aquellos casos en los que la testeabilidad constituye un atributo de calidad deseable del sistema. Cuando los tests son hechos antes que el cdigo a testear, el desarrollo de los mismos es guiado por los requerimientos y especificaciones del software; en el caso contrario, existe el riesgo de que los tests sean creados para satisfacer la implementacin, y no necesariamente los requerimientos. En TDD, la idea principal consiste en escribir los tests antes que el cdigo a ser testeado. El desarrollador entonces, trabaja agregando funcionalidad de a pequeos pasos, utilizando un framework de testing, que provee los mecanismos para la ejecucin de los test de unidad automticamente. El uso de esta prctica, adems, lleva a que los programadores implementen cdigo que de manera directa puede ser testeado automticamente; es decir, que se incluyan, por ejemplo, mtodos y funciones que devuelvan valores significativos para ser comparados con los resultados esperados. Los casos de test se van acumulando a travs de las iteraciones, formando una base que se utiliza como tests de regresin. stos se ejecutan continua y automticamente, lo que permite que se pueda determinar fcilmente si los nuevos cambios afectan negativamente la funcionalidad del sistema. Gracias a esto, TDD permite que cada nueva funcionalidad pueda ser integrada al sistema casi sin generar problemas. Otros beneficios del testing automticos incluyen: Produccin de un sistema confiable. Mejora en la calidad del testeo. Reduccin del esfuerzo a la hora del testing y minimizacin del programa.
La consigna de TDD, formulada por Beck, Rojo/Verde/Refactorizar, define su ciclo de desarrollo. En cada iteracin el desarrollador debe realizar pequeas decisiones de diseo e implementacin, e incrementar la funcionalidad (generalmente no ms de una pieza de funcionalidad por da laboral) a una taza relativamente consistente. Una regla importante es: "Si no puede escribir el test de lo que se est a punto de codificar, entonces no debera codificar en este momento". Partes del ciclo: Rojo: El primer paso del ciclo es, como ya se ha dicho, la creacin de tests fallidos. Estos tests son de caja blanca, ya que se hacen teniendo en cuenta cual ser la lgica interna del cdigo sobre el que ser utilizado. El hecho de que el test en un principio no funcione (e incluso podra no compilar) es importante, ya que la transicin de un estado al siguiente define el modo de verificacin de la implementacin. Verde: En el segundo paso se modifica el cdigo de forma simple y rpida para que pase el test. Esta solucin podra no ser eficiente e incurrir en repeticin de cdigo y malas prcticas. Hay que tener en cuenta que una nueva funcionalidad no es considerada propiamente implementada a menos que todos los test de unidad realizados para l, y todos los tests de unidad realizados durante todo el desarrollo del cdigo, resulten satisfactorios; es decir, que el nuevo cdigo no afecte funcionalidad anterior. Refactorizar: Finalmente, el tercer paso consiste en eliminar las repeticiones de cdigo y arreglar, en la medida de lo posible, el cdigo poco eficiente que haya sido implementado. El refactoring se define como transformacin que preserva el comportamiento, es decir, la reestructuracin del cdigo no debe modificar su funcionalidad externa. Para esto se pueden utilizar los mismos tests como soporte de 4
verificacin. La refactorizacin debe hacerse de a pequeos pasos para poder deshacer las acciones en caso de que se generen problemas. La ventaja principal de utilizar un ciclo tan dinmico viene desde el punto de vista del costo de cambio. Este conocido principio de la Ingeniera de Software dice que mientras ms tiempo permanezca un problema en el sistema de software, ms difcil y costoso ser eliminarlo. Como antes de agregar nueva funcionalidad se requiere que el sistema pase todos los tests histricos asociados a l, puede decirse que si en la siguiente iteracin surgen problemas, es muy probable que ese problema est indudablemente en el cdigo recientemente implementado, o en el que interacta inmediatamente con l. En consecuencia, los problemas son encontrados rpidamente, y su fuente puede ser fcilmente identificada. De todas maneras, cuando se encuentre tarde un defecto en el ciclo de desarrollo, se pueden escribir nuevos casos de test con la finalidad de exponer este defecto, antes de intentar arreglarlo.
Beneficios
[GEO02] [GEO03a] [WIL03] Comprensin del programa. El enfoque de TDD ayuda al entendimiento del cdigo, sobretodo en la etapa de mantenimiento, debido a que fomenta la explicacin del cdigo mediante casos de tests y el cdigo en s mismo; antes que una descripcin con palabras; asegurando, a su vez, que en todo momento los tests estn actualizados y su resultado es satisfactorio. Por otro lado, la prctica enfrenta la paradoja de que para entender una pieza de cdigo, el lector debe examinar, adems del mismo cdigo, otra pieza de cdigo (el test). Eficiencia. Como ya ha sido mencionado, la granularidad del ciclo test-then-code permite al desarrollador obtener un feedback constante, con lo cual, las fallas y/o problemas pueden ser identificados, junto a sus fuentes, en forma rpida y temprana. Base de Tests: La creacin de una base de tests que pueden ejecutarse automticamente, y que va incrementndose a lo largo del desarrollo, facilita la extensin y el mantenimiento del sistema. 6
Inyeccin de defectos. Durante la etapa de mantenimiento y debugging de un sistema, los problemas en el cdigo son generalmente emparchados, alterando efectivamente sus propiedades, pero sin examinar ni actualizar la especificacin y el diseo del sistema. Esto genera una cantidad de nuevos defectos en el cdigo. En caso de tener los tests de regresin a disposicin del programador, estos defectos pueden ser encontrados rpidamente, reduciendo as la posibilidad de que queden errores ocultos en el producto final. Diseo simple. Al no requerir ms diseo de lo que se ha implementado hasta el momento, que debera ser mnimo y simple, se asegura que ste tambin lo ser. Esto es generalmente bueno, ya que los diseos complejos tienden a ser defectivos.
Modelo en cascada:
Cdigo
Modelo en V:
Cdigo
Modelo TDD:
Cdigo
En un modelo de cascada, todas las subfases del testeo de unidad ocurren luego de que el cdigo es escrito, mientras que en V-Model, el diseo de los casos de testeo ocurre antes de la implementacin; finalmente en TDD, el diseo y construccin de los casos de testeo ocurre antes de la implementacin.
En comparacin, los ciclos de iteracin de TDD son ms pequeos y se encuentran bien definidos. Adems, el manejo de riesgos no es un rea de foco en TDD, y es generalmente delegado a un proceso externo a l.
10
El siguiente paso es conseguir que el test compile de la forma ms sencilla posible. Para esto se agrega la clase Calculator y se implementa la funcin de multiplicar. La implementacin ms sencilla en este caso es devolver 0. Con esta implementacin, el test compila pero falla, dando el resultado deseado, ya que provee una forma concreta para medir el xito y el fracaso. Clase calculadora implementada de la forma ms sencilla posible: Calculator.h class Calculator { public: int multiply(int term_lhs, int term_rhs) { return 0; } };
11
El siguiente paso es llegar al estado verde, es decir, lograr pasar el test. Esto tambin debe hacerse en la forma ms fcil posible. En este caso, se falsificar el resultado devolviendo el valor 15 de forma constante. Es claro que esta no es la implementacin correcta, pero sirve para verificar que el test funciona. Implementacin falsificada de la calculadora: Calculator.h class Calculator { public: int multiply(int term_lhs, int term_rhs) { return 15; } };
En el paso anterior, se alcanz el estado verde en el ciclo de TDD. El siguiente paso es refactorizar el cdigo para obtener la implementacin correcta de la aplicacin. Esto se hace mediante la introduccin gradual de las variables para hacer la multiplicacin. Implementacin refactorizada para el test de la calculadora: Calculator.h class Calculator { public: int multiply(int term_lhs, int term_rhs) { return term_lhs * 5; } };
En el ejemplo anterior un valor constante fue cambiado por una variable. Cuando estos valores son quitados de la implementacin tests adicionales pueden ser realizados. Cuando se adicionan los nuevos test, la prueba falla y debe programarse la implementacin correcta. Test adicional de Calculadora: CalculatorTest.cpp #define BOOST_TEST_MODULE calculatorTest #include <boost/test/unit_test.hpp> #include "Calculator.h" BOOST_AUTO_TEST_CASE(testMultiplication) { Calculator c; BOOST_CHECK_EQUAL(c.multiply(7, 7), 49); }
12
En esta parte se ha descripto el ciclo de trabajo y el ritmo de TDD. Se ha demostrado cmo los test pueden ser escritos antes de la implementacin. El ejemplo era muy simple y los pequeos pasos no eran necesarios para un problema tan trivial, la implementacin podra haber sido realizada de manera directa. Los test se han aadido con ejecutados peridicamente durante el desarrollo del ciclo de TDD. Los test que produce el proceso de TDD es una documentacin de diseo de bajo nivel del sistema. Se encuentran escritos en un lenguaje que los programadores entienden. Cuando los test se ejecutan regularmente se asegura que la documentacin se mantiene actualizada.
13
Los test no deben depender unos de otros para ser ejecutados. Para lograr test bajamente acoplados y cohesivos, estos no deberan requerir acceso a componentes externos (como ser, comunicaciones con una base de datos, redes o sistemas de archivos), ni algn tipo de configuracin manual antes de ser ejecutados. Test de rpida ejecucin. Si el conjunto de test toma demasiado tiempo en ejecutarse, existe el riesgo de que los desarrolladores no los ejecuten todos antes de realizar modificaciones. Buena Legibilidad. Los test escritos deben ser fciles de leer y entender. Su intencin debe ser tan clara como sea posible. Para ayudar a esto, los datos utilizados como entrada y salida tambin deberan ser claros, y ayudar al seguimiento de los tests. Datos Simblicos. Utilizar una nica constante para significar ms de un parmetro (por ejemplo, el mtodo suma(a,b) puede recibir las constantes 2 + 3, pero nunca 2 + 2). Datos Reales - Datos tomados de la realidad. Esta tcnica es til cuando se testean sistemas de tiempo real que utilizan estmulos de eventos externos obtenidos durante la ejecucin; cuando deben aparearse los resultados del sistema actual con aquellos de un sistema previo (testing paralelo); y en la refactorizacin de simulaciones que requieren siempre las mismas respuestas, especialmente cuando el problema puede recaer en la precisin de nmeros de punto flotante. Datos Evidentes: Incluir en el test tanto los resultados esperados como los obtenidos, haciendo su relacin evidente. Buena programacin. El cdigo de testing debe ser tratado como cdigo de produccin. Las mismas reglas de un buen diseo aplican a ambos, utilizando la refactorizacin cuando sea necesario.
estos casos es utilizar objetos que acten como la base de datos, pero que en realidad funcionan en memoria local. Self Shunt. Para testear la comunicacin entre objetos, lo mejor es hacer que el objeto testeado se comunique directamente con el caso de test, de modo de poder verificar as los resultados esperados de la comunicacin. Generalmente este patrn requiere que se utilicen interfaces para definir esta comunicacin, que el caso de test debera implementar. Log String. Para obtener un registro claro de la secuencia en que ciertos mensajes (operaciones) son llamados, se mantiene un registro en un string al que se agregan nombres cuando un mensaje es llamado. Este patrn suele utilizarse junto a Self Shunt. Crash Test Dummy. Ciertas partes del cdigo raramente son invocadas, por ejemplo, las excepciones. Para verificar que efectivamente stas funcionan, deberan ser invocadas utilizando objetos especiales cuya funcionalidad sea justamente esa. Un Crash Test Dummy es como un Mock Object, excepto que no se necesita construir el objeto completo, sino solo la parte sobre la que se quiere simular el error.
Regression Test. Cuando se encuentra un defecto, lo primero que debe hacerse es escribir un test lo ms simple y pequeo que se pueda, que falle, y que una vez que sea satisfactorio, signifique que el defecto fue arreglado. Estos tests, de haber tenido un conocimiento perfecto de antemano, hubiesen sido creados en el momento de la produccin original. Muchas veces la aparicin de estos defectos indica que debe realizarse una refactorizacin del sistema.
17
Para facilitar la implementacin de funcionalidad que trabaja con colecciones de objetos, se sugiere que en primera instancia se realice sin las colecciones y que luego se extienda para soportarlas.
18
Herramientas
Debido al gran xito que esta metodologa est teniendo en el mundo de la ingeniera del software, son muchas y variadas las herramientas que se han ido desarrollando hasta da de hoy. Algunas han surgido en forma de frameworks, otras en formato plug-in bajo el control de algn browser o incluso como libreras para su uso en plataformas de programacin. Quizs el formato en el que ms usado ha sido este tipo de metodologa haya sido el de los frameworks que consisten en entornos que facilitan la creacin, ejecucin y organizacin de pruebas unitarios. Todos los frameworks poseen sus propias funciones y atributos de clase de test que pueden ser utilizados para incluirlos en la plataforma de desarrollo utilizando el lenguaje correspondiente de forma que puedan ser manejados los test necesarios en cada momento.
Familia xUnit
[MES07] El trmino xUnit se refiere a cualquiera de los miembros de la familia de los Frameworks para testing de unidad, que comparten ciertas caractersticas comunes. La mayora de los lenguajes de programacin actuales usan por lo menos una implementacin de xUnit. Generalmente los tests son codificados en el mismo lenguaje que se est utilizando, y aunque no es estrictamente necesario, es una estrategia que facilita muchsimas cosas; no solo permite una conexin directa con la API, sino que requiere menos esfuerzo por parte de los programadores para la creacin de los tests.
Las caractersticas bsicas de los frameworks de tipo xUnit son: Entorno especializado. Dado un conjunto de mtodos de prueba, el framework proporciona una serie de test que se ejecutan devolviendo los resultados de una forma clara. SetUp o configuracin inicial. Para facilitar la creacin de tests compartidos, se pueden establecer una serie de reglas o mtodos que se ejecutan de forma previa al resto. Funciones predefinidas. Un framework, proporciona un conjunto de funciones prediseadas que permiten evaluaciones ms expresivas de acuerdo a las necesidades reales que pueden darse durante el flujo de una aplicacin. Proveen soporte para las siguientes tareas: Especificar un test como un Test Method Especificar los resultados esperados dentro del Test Method en forma de aserciones. Crear una agregacin de tests (test suites) que pueden correrse como una nica operacin. Ejecutar uno o ms tests para obtener un reporte con sus resultados.
19
JUnit
[BEC05] JUnit es un framework de testing de regresin para Java, en donde pueden escribirse tests de unidad durante el desarrollo del sistema. JUnit permite ejecutar los tests para verificar cuanto se desva el cdigo hecho de sus objetivos originales. El testing de integracin confirma que los diferentes subsistemas funcionan de manera correcta cuando son comunicados. El testing de aceptacin simplemente busca confirmar que la aplicacin haga lo que el cliente espera de l. Los tests de unidad son los que verifican una nica pieza de funcionamiento, que, en el caso de Java, podra tratarse de una clase. Hay una focalizacin fuerte sobre estos tests unitarios que verifican los bloques fundamentales de un sistema, de a uno a la vez, en lo que se denomina testing a nivel de mdulos. Esto lleva a un desarrollo de test suites que pueden ejecutarse en cualquier momento, asegurando que los cambios hechos en el cdigo y la refactorizacin no afectarn ninguno de los subsistemas de forma imprevista u oculta. Ejemplo de utilizacin de JUnit [BEC05]
Escribiendo un caso de test. Tanto en XP como en TDD, la consigna principal dicta que escribir y ejecutar tests debera ser fcil. Hacerlo con JUnit es tan simple como: 1. Crear una subclase de junit.framework.TestCase. 2. Crear un constructor que tenga por lo menos un parmetro String que indica su nombre, y que llame a super(name). 3. Implementar uno o ms mtodos que realizarn el testing. Estos mtodos no deben recibir ni devolver parmetros, y sus nombres deben comenzar con el prefijo test. En el siguiente ejemplo se crea el caso de test SimpleTest:
package org.example.antbook.junit; import junit.framework.TestCase; public class SimpleTest extends TestCase { public SimpleTest (String name) { super(name); } public void testSomething() { assertTrue(4 == (2 * 2)); } }
Ejecutando los casos de Test Las clases TestRunner, provistas por JUnit, se utilizan para ejecutar todos los tests que cumplan la condicin 3 dada anteriormente. 20
Los TestRunners ms populares son junit.textui.TestRunner y junit.swingui.TestRunner. El resultado de la ejecucin de un TestRunner por lnea de comandos, quedara de la siguiente manera:
java junit.textui.TestRunner org.example.antbook.junit.SimpleTest . Time: 0.01 OK (1 tests)
El punto (.) indica que el test se est ejecutando, y en este caso haba solamente uno, testSomething. Con el TestRunner Swing, se indica con verde que el test fue satisfactorio y rojo si fue fallido. Asercin de los resultados esperados El mecanismo por el cual JUnit determina si un test fue satisfactorio o no, es mediante las sentencias assert. Un assert es una simple comparacin entre un resultado esperado y el valor realmente obtenido. Hay algunas variantes entre los mtodos assert para cada tipo de dato primitivo, para los Strings y para los Objects, cada uno con los siguientes formatos: assertEquals(expected,actual), assertEquals(String message, expected, actual). Este tipo de asercin espera que expected.equals(actual) devuelva true, o que ambos objetos sean null. La asercin de equivalencia entre doubles permite adems especificar un rango, para evitar problemas con errores de punto flotante. assertNull(Object object), assertNull(String message, Object object). Verifica que el objeto al que hace referencia sea null. assertNotNull(Object object), assertNotNull(String message, Object). Verifica que el objeto al que hace referencia no sea null. assertSame(Object expected, Object actual), assertSame(String message, Object expected, Object actual). Esta asercin especifica una condicin ms estricta que equals, ya que compara la identidad de los objetos usando expected == actual. assertTrue(boolean condition), assertTrue(String message, boolean condition). La asercin falla si la condicin es falsa. fail(), fail(String message). Esta asercin siempre fuerza a que el caso de test falle, esto es til para cerrar caminos hacia parte del cdigo que no debera alcanzarse.
Boost
[BOO11] El Framework de Test de Unidad Boost Test Library provee una automatizacin del testing fcil y flexible en C++, ayudando en la implementacin y organizacin de los test de unidad. Especficamente provee facilidades verstiles para: Simplificar la implementacin de los tests mediante la utilizacin de diferentes herramientas de testing. Organizar los casos de test en arboles de test. Reportar el procesamiento de parmetros en tiempo de ejecucin.
21
El Framework mantiene un seguimiento de todas las aserciones satisfactorias/fallidas, provee verificacin del progreso del testing y genera un reporte con los resultados en diferentes formatos. Para la ejecucin, se proveen test runners para lnea de comandos que pueden inicializar y correr los tests requeridos. Dependiendo de las opciones de compilacin seleccionadas, una implementacin por defecto de la funcin main() puede generarse automticamente. Utilizacin La funcin main es la responsable de la inicializacin del ambiente y de la creacin de reportes. Adems, incluye una comunicacin con el usuario por la que puede ingresarse informacin necesaria. Para integrar un test al framework debera proveerse la siguiente funcin:
Su principal responsabilidad es la de crear e inicializar el rbol de tests, que consiste en casos de test y test suites. Ejemplo: void my_test_function() { ... } test_suite* init_unit_test_suite( int argc, char* argv[] ) { test_suite* test = BOOST_TEST_SUITE( "Master test suite" ); test->add( BOOST_TEST_CASE( &my_test_function ) ); return test; }
NUnit
[NUN11] Se trata de un framework opensource para pruebas unitarias de sistemas realizados con la plataforma Microsoft .Net. Es un framework desarrollado en C#. Utiliza atributos personalizados para interpretar las pruebas y provee adems mtodos para implementarlas. En general, NUnit compara valores esperados y valores generados, si estos son diferentes la prueba no pasa, caso contrario la prueba es exitosa. Algunas de las caractersticas de este framework son: 22
Pruebas de unidad para lenguajes.NET y Mono. Provee un ainterfaz grfica para ejecutar las pruebas. Sigue el modelo JUnit. Integracin con Visual Studio en cualquiera de sus versiones soporte de archivos de configuracion Es extensible Autodetecta cambios de los ensamblados Extensiones: o NUnit.Forms o Pruebas de elementos de los interfaces de usuario en Windows Forms. o NUnit.ASP o Pruebas de elementos en ASP.NET
Funcionamiento NUnit basa su funcionamiento en dos aspectos, el primero es la utilizacin de atributos personalizados que le indican al framework de NUnit qu es lo debe hacer con determinado mtodo o clase, es decir, estos atributos le indican a NUnit como interpretar y ejecutar las pruebas implementadas en el mtodo o clase. El segundo son las aserciones, que son mtodos del framework de NUnit utilizados para comprobar y comparar valores. Atributos La versin 1x de NUnit utilizaba las convenciones de nombrado del framework de .NET, pero desde la versin 2 en adelante NUnit usa atributos personalizados. Dado que el framework de NUnit no deriva de otra clase o framework, el desarrollador puede elegir libremente el nombre de la prueba. TestFixture
Este atributo se utiliza para indicar que una clase contiene mtodos de prueba. En versiones anteriores para poder utilizar este atributo se deba extender (heredar de) la clase TestCase,mientras que, a partir de la versin 2, esto no es necesario, situacin que hace mucho ms flexible el uso del atributo. De todas maneras, existen algunas restricciones, como por ejemplo que la clase debe tener un constructor por defecto y debe ser publica para que el framework NUnit pueda accederla. ExpectedException
Este atributo como su nombre lo sugiere, tiene como funcionalidad indicar que la ejecucin de un mtodo prueba va a lanzar una excepcin. El atributo tiene como parmetro el tipo de excepcin que se espera que lance el mtodo, el framework ejecuta la prueba y si se genera una excepcin del tipo especificado entonces la prueba es exitosa, si por el contrario se genera una excepcin de tipo diferente al especifico la prueba no lo es. La excepcin debe ser exactamente la especificada en el parmetro del atributo
23
Suite
El atributo suite es utilizado para definir subconjuntos de pruebas de acuerdo a las preferencias del usuario, sin embargo este atributo ha sido reemplazado desde la versin 2 debido al nuevo mecanismo dinmico de ejecucin de pruebas del framework (en modo grfico se puede seleccionar qu pruebas se desean ejecutar utilizando el atributo category, adems se pueden agrupar dentro de una estructura marcada como TestFixture). En general es soportada para proveer compatibilidad hacia atrs. En las nuevas versiones del producto no se puede correr suites. Category
El atributo category provee una alternativa a las suites para trabajar con grupos de pruebas. Cualquiera, ya sea casos de prueba individuales o Fixtures, pueden ser identificadas como pertenecientes a una categora de pruebas en particular. Ya sea en modo grafico o en modo consola se puede especificar que categoras se excluyen o incluyen en la ejecucin. Cuando se utilizan categoras, solo las pruebas de la categora seleccionada son ejecutadas. Las pruebas incluidas en las categoras que se excluyen de la ejecucin no son reportadas. Para excluir o incluir determinada categora en el modo consola incluya el parmetro /exclude o /include seguido del nombre de la categora. En el modo grfico existe una pestaa denominada categoras. Es importante anotar que esta funcionalidad solo se encuentra presente en la versin 2.2 del producto. Este atributo puede utilizarse junto con TextFixture o Test Explicit
Este atributo ocasiona que una prueba o un Fixture sean ignorados por el programa y no sean ejecutados a menos que se especifique lo contrario. Si una prueba o un Fixture con el atributo Explicit es encontrado durante la ejecucin, el programa la ignora. El icono de la prueba o el Fixtures se coloca amarillo y es colocado en el reporte de pruebas no ejecutadas. Esto es til cuando se desea, por ejemplo no ejecutar todas las pruebas sino una seleccin de ellas. Las pruebas marcadas con Explicit pueden ser ejecutadas si explcitamente se le indica al programa que lo haga y esto se hace seleccionando la prueba y oprimiendo el botn run en el entorno grfico o escribindola en la ventana de comandos. Ignore
Utilizado para indicar que se debe ignorar determinada prueba o Fixture, El programa ve el atributo y no ejecuta la prueba o pruebas. El icono se coloca amarillo y la prueba es reportada como no ejecutada. Esto es til para inhabilitar pruebas temporalmente, es decir, este atributo es til para marcar una prueba o Fixture, si no se desea ejecutarla momentneamente, en vez de comentar el mtodo o la clase, ya que de todas maneras va a ser compilada junto con el resto del cdigo pero no ser tenida encuentra a la hora de ejecutar las pruebas. Aserciones Las aserciones son mtodos estticos que la clase assert provee para realizar comparaciones y condiciones de prueba. Las aserciones ms utilizadas son las de comparacin, stas reportan tanto el valor esperado como el valor actual. El valor esperado es siempre el primer parmetro en un mtodo assert, por ejemplo: Assert.AreSame(object expected, object actual, string message ); 24
En general se tiene dos mtodos sobrecargados: Assert.AreSame y AssertAreEqual, el primero verifica que el mismo objeto est referenciado por ambos argumentos, es decir que las dos referencias a objetos apunten al mismo objeto, por ejemplo: Assert.AreEqual (int expected, int actual, string message ); El Segundo esta sobrecargado para trabajar con la mayora de los tipos comunes(int, integer, double, single, string, etc.), por ejemplo: Assert.AreEqual(string expected, string actual, string message ); En una prxima versin se podr comparar arreglos. Es importante destacar que los mtodos sobrecargados proveen la funcionalidad de comparar objetos de diferentes tipos y obtener el resultado apropiado, por ejemplo la siguiente prueba es exitosa: Assert.AreEqual(3, 3.0, Son Iguales );
25
Adoptando TDD
[AEK09] [AST03] Para la adopcin del TDD se requiere que el desarrollador aprenda nuevas tcnicas de desarrollo de software y por lo menos del manejo de una herramienta. Esta nueva herramienta es obligatoria y se trata de un framework de testeo de unidad. El aprendizaje de una nueva herramienta reduce la productividad y calidad al comienzo. Hay un esfuerzo por aprender y entender nuevas ideas y para ver como esto se adapta al entorno de desarrollo actual. En el primer proyecto donde se utiliza una nueva herramienta o tcnica, los desarrolladores son menos efectivos, lo que hace que ste tome ms tiempo que el usual. El beneficio real de una nueva idea no es ganado hasta que la curva de aprendizaje es superada. Es difcil decir en trminos generales cuanto tiempo tomar; pero para obtener un mayor beneficio al final, mayor ser la curva de aprendizaje. La longitud de dicha curva y la grandeza del beneficio puede ser estimada preguntndole a alguien que ya se encuentre utilizando la misma tcnica o herramienta. La respuesta del especialista debe ser crticamente evaluada, dado que la persona puede tener intereses sobre el producto por el cual le fue consultado. Pair programming es un mtodo de desarrollo de software gil que tiene su origen en XP. Significa que dos personas trabajan juntas en una nica computadora. Este mtodo puede ser utilizado para aliviar la curva de aprendizaje del equipo. Es ms fcil disciplinar en la escritura de test cuando se est trabajando con alguien ms. Aprender TDD sin un entrenamiento externo puede ser difcil. El equipo puede ser mandado a seminarios externos o cursos de entrenamiento. La persona a cargo de los mismos debe tener experiencia prctica en el mtodo de TDD y ser capaz de ensear al equipo enfocndose en los aspectos prcticos, por ejemplo, a travs de pair programming como se ha mencionado anteriormente. En la aplicacin del mtodo pueden surgir una gran cantidad de problemas. Por ejemplo, los desarrolladores pueden encontrar difcil llevar a la prctica el TDD en partes complejas del sistema y en la escritura de tests para cada una de las partes del cdigo fuente. Otras limitaciones, pueden referirse a los frameworks de testeo de unidad. Las aplicaciones con interfaz grfica son difciles de testear. Por otra parte, los desarrolladores pueden tender a abandonar la escritura de tests de unidad durante los perodos de tiempo cercanos al lmite de entrega, dado que consideran ms importante completar todas las caractersticas que le fueron solicitadas entregando las funcionalidades prometidas.
26
La adopcin del mtodo debe ser positiva para los desarrolladores, su beneficio debe estar claro. Si el equipo de desarrollo de software no se da cuenta del porqu de los beneficios del TDD, es probable que su utilizacin falle.
27
Conclusiones
TDD es una prctica emergente que tiene su origen en Extreme Programming (XP), y que procura producir software de alta calidad rpidamente, sin desatender los cambios inevitables en los requerimientos y el diseo. Este mtodo de desarrollo de software se utiliza generalmente en procesos giles. Los tests de unidad creados como parte del TDD constituyen una herramienta poderosa que debe ser utilizada. Mejora la calidad del software en una forma que agrega valor al negocio. Para adoptar completamente TDD y utilizarlo como un mtodo de diseo y desarrollo, es posible encontrar ciertos obstculos debido a la diferencia en su naturaleza respecto a las maneras tradicionales de desarrollo. Dicha adopcin requerir la predisposicin y el entendimiento de cada uno de los individuos que se encargarn del desarrollo.
Puede concluirse que TDD tiene potencial y que debe ser seriamente evaluado en la prctica para su utilizacin pero sin perder de vista las necesidades concretas del software a desarrollar y las posibilidades de adaptacin del equipo de desarrollo.
28
Bibliografa
[AEK09] Aekmelaeus, W. Test-Driven Development. Arcada University of Applied Sciences. Helsinki 2009. [AST03] Astels, D. Test-Driven Development: A Practical Guide. Pearson Education. 2003. ISBN 0-13-101649-0 [BEC02] Beck, K. Test Driven Development: By Example. Addison-Wesley Longman. 2002. ISBN 0321146530 [BEC05] Beck, K.; Andres, C. Extreme Programming Explained: Embrace Change (2nd Edition). Addison Wesley
2005. ISBN 0-321-27865-8
[BOO11] Boost Test Library: Unit Test Framework http://www.boost.org/doc/libs/1_35_0/libs/test/doc/components/utf/index.html. Accedida 24 de Octubre de 2011. [FRE09] Freeman, S.; Pryce, N. Growing Object-Oriented Software, Guided by Tests. Addison Wesley. 2009. ISBN-13: 9780321503626 [GEO02] George, B. Analysis and Quantification of Test Driven Development Approach. A thesis submitted to the Graduate Faculty of North Carolina State University in partial fulfillment of the requirements for the Degree of Master of Science. Raleigh 2002. [GEO03a] George, B.; Wiiliams, L. A structured experiment of test-driven development. Elsevier B.V. 2003. [GEO03b] George, B.; Williams, L. An Initial Investigation of Test Driven Development in Industry. Proceedings
of the 2003 ACM symposium on Applied computing. ISBN:1-58113-624-2
[KAR07] Karlesky, M.; Williams, G.; Bereza, W.; Fletcher, M. Mocking the Embedded World: Test-Driven Development, Continuous Integration, and Design Patterns. Embedded Systems Conference Silicon Valley (San Jose, California) ESC 413, April 2007 [KAU03] Kaufman, R.; Janzen, D. Implications of Test-Driven Development A Pilot Study. OOPSLA '03 Companion of the 18th annual ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications. 2003. ISBN:158113-751-6
[MAD10] Madeyski, L. Test-Driven Development An Empirical Evaluation of Agile Practice. Springer Heidelberg Dordrecht London New York. 2010. ISBN 978-3-642-04287-4 [MES07] Meszaros, G. xUnit Test Patterns - Refactoring Test Code. Addison-Wesley. 2007. ISBN 13: 978-013-149505-0 [NUN11]NUnit.org Home Documentation http://www.nunit.org. Accedida 24 de Octubre de 2011. [WIL03] Williams, L; Maximilien, M; Vouk, M. Test-Driven Development as a Defect-Reduction Practice. 14th International Symposium on Software Reliability Engineering. 2003. ISBN: 0-7695-2007-3
29