Nota del autor

Si la entrada que estás leyendo carece de imágenes, no se ve el vídeo que teóricamente lleva incrustado o el código fuente mostrado aparece sin formato, podéis conocer los motivos aquí. Poco a poco iré restableciendo la normalidad en el blog.
Este blog es un archivo de los artículos situados previamente en Lobosoft.es y ha dejado de ser actualizado. Las nuevas entradas pueden encontrarse en www.lobosoft.es. Un saludo,
Lobosoft.
Mostrando entradas con la etiqueta TDD. Mostrar todas las entradas
Mostrando entradas con la etiqueta TDD. Mostrar todas las entradas

jueves, 19 de febrero de 2009

Doubler, automatizando la generación de pruebas unitarias

Cuando llevamos a cabo un desarrollo guiado por pruebas (TDD) ideal, las pruebas serán escritas con antelación al código que deberá implementar la funcionalidad deseada, y a continuación se escribirá este último, de forma tal que supere aquellas. Es decir, como hemos comentado en varias ocasiones, las pruebas unitarias forman parte de las especificaciones de los requerimientos que deberemos cumplir. Sin embargo, este entorno ideal de iteraciones (escribir pruebas, codificar, pasar las pruebas y refactorizar) no siempre puede darse. En ocasiones, por limitaciones de tiempo se prima el que la funcionalidad esté lista sin llevar a cabo pruebas unitarias, o bien “heredamos” código ya implementado, y antes de meternos de pleno con él optamos por crear una batería de pruebas que nos ayude a programar con algo más de seguridad.


En casos como estos, es bastante útil contar con generadores de código que automaticen la creación de un “esqueleto” de pruebas unitarias. En el caso de usar el framework de pruebas MSTest de Microsoft, bastará con tener un Visual Studio para que, seleccionando los componentes a probar, genere un proyecto de pruebas unitarias que podremos “rellenar”. Incluso usando Pex podemos conseguir pruebas unitarias que validen casos extremos, ya que realiza un análisis de nuestro código. Por cierto, esta herramienta de Microsoft que aún está en alfa únicamente funciona con las ediciones Team System de Visual Studio.


Sin embargo, no siempre queremos o podemos usar el framework de pruebas que nos propone Microsoft. Bien por políticas de empresa, por licenciamiento, o porque preferimos cualquier otro, la generación de las pruebas para MSTest requiere realizar una serie de cambios sobre el código autogenerado, como renombrar atributos de clases y métodos y refactorizar un poco los fuentes. Si preferimos NUnit o MbUnit para implementar nuestras pruebas, podemos usar Doubler para, a partir de un ensamblado .NET, generar el esqueleto de pruebas unitarias de forma automática. Doubler está disponible en el sitio de Google Code, y se trata de un add-in para Lutz Roeder’s Reflector, que posiblemente conozcáis bien si soléis trabajar con .NET. Su instalación es muy sencilla (basta con añadir la DLL correspondiente desde el menú de gestión de add-ins), y permite acceder a un menú contextual desde el que le indicaremos qué deseamos hacer con una determinada clase. Desde el mismo podemos llevar a cabo diversas acciones:




  • Generación de pruebas: Con botón derecho sobre un tipo inmediato, la generación de pruebas hace aparecer una lista de propiedades configurables (lenguaje de generación, framework de pruebas, que incluye MSTest, NUnit y MbUnit, inclusión de atributos…) para la generación automática de código de pruebas. Tras pulsar sobre el botón de generación (que es tan grande que no lo parece), se creará un fichero de código de pruebas que deberemos completar con los Asserts correspondientes.

  • Grabación de un generador: Se aplica a tipo abstractos, creando un stub para las pruebas. Un Test Stub es un objeto usado en un tests para reemplazar al componente real. En nuestro caso, el Recording Test Stub puede ser usado para verificar salidas indirectas de las pruebas. En cierto modo es como crear un inspector de comportamiento para el componente que está siendo sometido a pruebas.

  • Generador de Fakes: Crea un falso objeto, basado en una clase abstracta, para ser usado en las pruebas sobre una clase base. El falso objeto, o fake, deberá dar una implementación alternativa a la funcionalidad que el objeto al que reemplaza.

  • Wrapper o generador de interfaces: Aplicado sobre un tipo inmediato, crea una copia de la interfaz del tipo seleccionado, así como una implementación de la misma que redirige todas las llamadas a una instancia privada del mismo a través. Esto permite un desacoplamiento de las pruebas respecto al objeto.


La verdad es que el código que crea es bastante claro y nos puede ahorrar, como decía tiempo y trabajo repetitivo con un par de clics de ratón. Si al mismo le sumamos que Pex también cuenta ya con un add-in para Reflector (y que funciona siempre que tengamos Pex instalado en nuestra máquina, es decir, si contamos con un Visual Studio TS), lo cierto es que la herramienta se va a convertir en un compañero aún más inseparable de lo que ya lo era.


A continuación muestro algunas capturas básicas con la generación de unos métodos de prueba para una clase muy simple, a modo de Hola Mundo con Doubler ;) .





Un par de bloques de nuestro código a probar...


La estructura de la DLL para Reflector.


El menú contextual añadido por el add-in Doubler.


Estableciendo las propiedades para el código generado


Y nuestro código de pruebas, listo para ser completado y usado.

martes, 17 de febrero de 2009

ALM, la gestión del ciclo de vida del software

Esta mañana asistí, junto a unos compañeros, a un seminario sobre el ciclo de vida del software (ALM) desde la perspectiva de Microsoft, es decir, mediante el uso de las herramientas que Team Foundation Server y la familia de productos de Visual Studio Team System nos ofrecen.


La verdad es que he de manifestarme como un convencido de las metodologías y su repercusión en el buen resultado de los proyectos de desarrollo. De poco nos sirve contar con buenos desarrolladores si los continuos cambios de requisitos terminan por minar su autoestima y su convicción de que el trabajo que realizan es el adecuado. Es decir, si son profesionales sometidos a todas las ocurrencias que tan genialmente plasma Ender cada semana en su Sinergia sin control.


Volviendo al seminario que nos ocupa, el ponente, Hadi Hariri, recientemente laureado como MVP C# 2008 de Microsoft, afrontó los contenidos con una aproximación que me pareció muy adecuada: plantear los problemas y posibles soluciones desde la perspectiva de la adopción de metodologías ágiles como Scrum y el desarrollo guiado por pruebas (el archifamoso TDD), para después, sin obviar que existen otras herramientas disponibles gratis, o con menor coste, plantear cómo se afrontaría un proyecto de desarrollo con las que nos ofrece Microsoft, con una integración bastante adecuada entre ellas: la gestión de plantillas de proyecto, documentación (especificación de requisitos, o historias de usuario en metodologías más ágiles), la asociación entre tareas, código desarrollado, pruebas unitarias y control de código fuente, integración continua… Sin duda, todo lo que vimos ya está inventado, y en mayor o menor medida, con más o menos configuración, podemos conseguirlo con otras herramientas libres o más baratas, aunque lo cierto es que para desarrollos .NET, la suite de utilidades que nos ofrece Microsoft es bastante interesante, aunque también habría que sentarse a echar cuentas sobre las licencias que tanto software y equipo nos requeriría. Posiblemente para un equipo medio o grande, es una buena opción, pero para desarrollos sobre múltiples plataformas o un equipo pequeño el traje, creo, puede quedarnos algo grande.


También estuvimos viendo un poco lo que está por venir con Visual Studio 2010, su editor de código en WPF, el generador de diagramas de secuencia para los objetos, similar al generado por herramientas como SequenceViz, que probé hace unos meses y me pareció bastante interesante. Y, por último, asistimos a la generación de pruebas sobre la interfaz de usuario, funcionales y de integración, gracias a Microsoft Camano, una herramienta para testers que permite, entre otras florituras, la grabación de videos de pruebas con sus resultados, la reproducción automática de pruebas grabadas en modo “macro”, de forma similar a como se llevan a cabo con NUnitForms o Selenium, para aplicaciones web y WPF (de lo que deduzco que los fans de Silverlight tendrán también aquí motivo de alegría y diversión futuras).


En resumen, una más que interesante charla, que nos hace augurar un futuro a medio plazo bastante prometedor para todos aquellos a quienes nos gusta “cacharrear” con el software. ¿Y vosotros, habéis jugado un poco con la (algo inestable aún, eso sí) CTP de Visual Studio 2010? ¿Qué os parece la tendencia de Microsoft a “reinventar la rueda” (haciéndola, eso sí, un poco más redonda y aplicándole mejoras como los radios al invento :) )?

lunes, 19 de enero de 2009

Testing Experience


Esta tarde, al llegar a casa después del trabajo me he encontrado con una grata sorpresa. Tenía en el buzón el cuarto número de la edición impresa de la revista Testing Experience. Creo recordar haber comentado su existencia por estos lares en alguna ocasión, y ahora vuelvo a recomendaros una publicación más que interesante dentro del mundo del desarrollo del software y, en particular, de la parcela correspondiente a las pruebas del mismo.


Las revistas están disponibles para su descarga en la web de la revista,aunque es posible suscribirse de forma gratuita para recibirlas impresas. Aunque siempre abogo por el uso del ordenador para la lectura de artículos técnicos y la consulta de libros de informática, hay ocasiones (como cuando el equipo de trabajo las consulta de forma intensiva, o pueden compartirse con colegas, compañeros y amigos) en las que creo que es incluso más interesante (y ecológico, pese a lo que pueda parecer) contar con un ejemplar impreso.


Además, y aunque resulte un poco off-topic, este mediodía cuando me dirigía a casa a almorzar (sí, envidiosillos, es la ventaja de vivir cerca del trabajo, jejeje) he visto dos cuervos sobrevolando la entrada del Parque Tecnológico. Aunque es habitual contemplar aves de paso, por estar ubicado cerca de la desembocadura del Guadalhorce, no es tan común que nos topemos con este córvido, aunque no es la primera vez que les veo por aquí. En cualquier caso, hoy su paso guarda un especial significado, ya que se celebra el bicentenario del nacimiento de Edgar Allan Poe, del que seguro que conocéis su poema El Cuervo.


Pues nada, lo dicho. Os dejo para sumergirme en la lectura de la revista. Y es que hay problemas causados por los bugs y problemas de diseño que no se han detectado por no llevar a cabo unas buenas prácticas de testing que dan más miedo que los cuentos del inmortal autor norteamericano ;) .

martes, 2 de diciembre de 2008

Pruebas de caja blanca automatizadas en .NET


Una de las tareas más tediosas a la hora de desarrollar pruebas unitarias sobre código existente es tener en cuenta todas las posibles entradas y flujos de ejecución. Sin embargo, es necesario (imprescindible incluso) un correcto control de ambos aspectos durante el desarrollo de nuestras aplicaciones. Durante el proceso de desarrollo, las prácticas recomendadas por metodologías como la Programación eXtrema (XP) y el Desarrollo Guiado por Pruebas (TDD) nos dicen que debemos escribir los tests necesarios para validar el código que estamos creando. Sin embargo, no se nos dice qué pruebas debemos escribir, aunque sabemos que las pruebas, si están bien escritas son, además de una herramienta insustituible para la verificación del código, un modo de reflejar mediante código las especificaciones que deberá cumplir nuestro código.


Por todo esto, Microsoft ha preparado un nuevo framework (sí, uno más, a mí también me sorprendió cuando me hablo del mismo un compañero de trabajo) que permite facilitar la tarea del desarrollador mediante la creación de pruebas unitarias mediante la inspección automática del código. Estoy hablando de Pex (Program EXploration), que puede ser descargado desde la página de Microsoft Research, y que durante su instalación nos adelanta una futura integración con Visual Studio 2010, el próximo IDE de la compañía. Aunque el sistema operativo recomendado es Windows Vista, no he tenido problema alguno para probarlo con mi Windows XP SP2 y Visual Studio 2008. Tras instalarlo, a ser posible incluyendo los complementos para Visual Studio, tendremos un nuevo grupo de programas con el propio Pex, una carpeta de ejemplos para juguetear un poco y una documentación bastante completa y muy interesante.


Ahora podemos hacer uso del mismo simplemente incluyendo una referencia a Microsoft.Pex.Framework en nuestro proyecto, y etiquetando adecuadamente las clases y métodos con los atributos PexClass y PexMethod respectivamente.



Hecho esto, podemos acceder al menú contextual dentro del código y seleccionar la opción “Run Pex Explorations”. Aparecerá un panel con los resultados de la exploración, y el análisis que ha llevado a cabo Pex en nuestro código.



Como se puede observar, podemos analizar las diversas entradas que Pex habrá usado como parámetros de entrada en nuestros métodos, un pequeño resumen o control de excepciones y el mensaje de error obtenido, si es el caso.



Si seleccionamos una de las entradas, aparecerá una zona con los detalles del código que Pex generará por nosotros para ejecutar la prueba correspondiente. Si esa entrada provoca una excepción, es posible automatizar incluso el control de la excepción, etiquetando el método que ejecutará la prueba para que la misma sea una excepción esperada.






En el cuadro de diálogo Herramientas->Opciones, podemos establecer una serie de configuraciones sobre Pex como, por ejemplo, la generación de informes. Si habilitamos dicha opción, en la carpeta destino de la compilación se creará una carpeta con el informe en formato HTML. Podemos observar en el mismo los tests que han sido generados y la cobertura que suponen sobre el código.





La verdad es que Pex pinta realmente bien. Parece una herramienta interesantísima a la hora de gestionar y generar las pruebas unitarias de forma automatizada. La documentación es muy completa e incluye, además del manual de uso de Pex, una serie de documentos sobre patrones de pruebas para un uso eficiente de Pex, o el uso de stubs. Conforme vaya profundizando en él iré dejando por aquí mis impresiones.


Ah, y no es lo único que se nos viene encima. Los chicos de DevLabs en Microsoft tienen en mente proyectos tan interesantes como CHESS, una herramienta para la búsqueda automática de interbloqueos, condiciones de carrera y otros heisenbugs en nuestro código concurrente.

El ascenso de Ícaro


El desarrollo guiado por pruebas o TDD nos permite codificar nuestras aplicaciones de una forma más segura, ya que ante cambios en el código existente o inclusión de nuevas funcionalidades, basta pasar nuevamente todas las pruebas (incluyendo, en su caso, las nuevas que sean pertinentes) para asegurarnos que las modificaciones no han alterado su funcionamiento anterior. Una de las herramientas que nos permiten llevar a cabo este desarrollo son los frameworks de prueba, de los que existen de todos los sabores y gustos conocidos para cada lenguaje de programación o plataforma de desarrollo. En el caso del .NET Framework podemos citar, entre otros, el extendidísimo NUnit en sus líneas de desarrollo 2.x y 3.x, MbUnit muy orientado a la extensibilidad del mismo, MSTest que viene “de serie” con Visual Studio (excepto las ediciones Express) y xUnit.net, que nació tras las lecciones aprendidas de otros frameworks de pruebas unitarias y que poco a poco va adquiriendo mayor peso entre la comunidad de desarrolladores.



Estos frameworks suelen consistir en un core de pruebas que nos permite, gracias al etiquetado mediante atributos de nuestras clases y métodos, la ejecución automatizada de los tests. También incorporan clases de extensión y demás funcionalidades, y suelen permitir la ejecución de las pruebas desde la propia consola del sistema, o a través de una interfaz gráfica que nos hace la vida más fácil a los usuarios de los mismos. Pues bien, días atrás estuve evaluando xUnit.Net como alternativa a NUnit de cara a nuevos desarrollos, y su inclusión dentro del proceso de integración continua que facilitan herramientas TeamCity, de la que me gustaría hablar algún día. El caso es que, probando xUnit.net, el GUI que ofrece “de serie” el framework es ciertamente triste, aunque sea una versión temprana del mismo. Así las cosas, me planteé probar su funcionamiento con alguna otra aplicación que permitiese llevar a cabo campañas de prueba de una forma más sencilla y con un mayor control sobre los resultados arrojados por los tests. Aunque la oferta a este respecto, por lo que pude ver, no es demasiado extensa (buscaba un GUI suficientemente flexible como para permitir la ejecución de pruebas con xUnit.net sin demasiado trabajo de configuración previa, o sin tener que desarrollar scripts en NAnt, MSBuild o similares), encontré mi opción ideal en Gallio, una plataforma de automatización, abierta y extensible, que puede integrarse con numerosos frameworks de pruebas en .NET. De hecho, es tan flexible que permite la ejecución de series de test desarrollados sobre diversos frameworks sin mayor problema. Incorpora un GUI, Icarus, cuya instalación y uso es tan simple como el propio GUI de NUnit, permitiendo además obtener informes muy vistosos como puede observarse en las diversas capturas que acompañan a la entrada de hoy.



El Explorador de Tests nos permite seleccionar aquellas pruebas que deseamos ejecutar.



Una ejecución de tests con un resultado ideal.



El Explorador de Tests correspondiente a la ejecución anterior.



El log de ejecución con algunos tests fallidos.


No voy a entrar demasiado en profundidad en la aplicación, ya que su uso es muy intuitivo y simple, y lo único de lo que quería dejar constancia es del interés que ha suscitado en mí precisamente por eso, porque permite incluso desarrollar nuevas pruebas sobre el código existente en un framework de pruebas distinto al ya existente, y pasar las pruebas en su totalidad desde una misma aplicación. En contra suya únicamente he notado una ligera lentitud en la carga y ejecución de los ensamblados que contienen las pruebas a pasar.



Un completo informe en HTML.


¿Y en vuestro equipo, desarrolláis basándoos en TDD? ¿Qué framework de pruebas usáis? ¿Cuál os gusta más y por qué?

martes, 4 de noviembre de 2008

Pruebas sobre la interfaz de usuario en aplicaciones Windows

Hay múltiples ocasiones en las que resulta necesario realizar pruebas sobre la interfaz de usuario de nuestras aplicaciones, y como bien saben quienes llevan a cabo desarrollo dirigido por pruebas (más conocido por su nombre anglosajón, Test Driven Development o, simplemente, TDD), esta capa del software, la más cercana al usuario, resulta más compleja a la hora de establecer una automatización sobre las pruebas. Existen, no obstante, opciones para llevar a cabo baterías de pruebas sobre la UI (User Interface), que dependerán del tipo de aplicación con la que estemos trabajando (consola, con interfaz gráfica, web…) y del lenguaje o plataforma de desarrollo. Hoy nos vamos a centrar en .NET y las pruebas en Windows Forms.


Una aplicación Windows en .NET no es más que una serie de clases, entre las que se incluirán controles de usuario y formularios, que van siendo presentadas e interactuando con el usuario a través de diversos eventos. La automatización de las pruebas, en este entorno, dependerá de ser capaces de simular la interacción del usuario con la aplicación a través de los propios controles de los formularios. Esto es factible, desde el propio código, si vamos instanciando los formularios y ejecutando sobre ellos determinadas acciones. Por ejemplo, podríamos crear un Formulario mediante


Form1 f = new Form1();

e interactuar con sus controles, bien porque conozcamos cómo se llaman, bien a través de reflexión. Sin embargo, al igual que para llevar a cabo pruebas unitarias sobre el código disponemos de frameworks tan adecuados como NUnit o XUnit.NET, para desarrollar pruebas sobre la UI podemos hacer uso de NUnitForms, una extensión de NUnit que permite realizar pruebas unitarias y de aceptación sobre aplicaciones Windows (Forms).


Si descargamos NUnitForms, veremos que además del propio framework, incorpora una aplicación llamada Recorder, que nos ayudará a “grabar” como si de una macro se tratase el test. Realmente sólo permite la grabación de tests básicos, por lo que si deseamos probar alguna funcionalidad más avanzada o un control de usuario específico que hayamos creado lo ideal será escribir la prueba a mano (o grabar una prueba más básica y ampliarla con aquellas características que el Recorder no haya sido capaz de gestionar). El funcionamiento es muy básico, y lo presentaremos mediante un ejemplo.


Imaginemos que deseamos comprobar el funcionamiento del siguiente formulario (Form1). Simplemente consta de una caja de texto (textBox1), un botón (button1), una lista (listBox1) y un par de etiquetas (label1, label2). El botón insertará en la lista los valores que vayamos escribiendo en el cuadro de texto. Una de las etiquetas contiene el valor constante “ítems”, y la otra se va actualizando con el número de elementos que contiene la lista.



El código del formulario es tan simple como esto:



[csharp]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace TestingUI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(textBox1.Text))
{
listBox1.Items.Add(textBox1.Text);
label1.Text = listBox1.Items.Count.ToString();
}
}
}
}
[/csharp]


Por tanto, una prueba podría ser insertar uno o varios elementos en la lista, y comprobar que el valor de la etiqueta coincide con el esperado. Creamos la aplicación, la compilamos, y abrimos el Recorder. Pulsaremos sobre File, Load, y seleccionaremos el fichero .DLL o .EXE que contenga los formularios sobre los que llevar a cabo la prueba. En el desplegable de la parte superior del Recorder, seleccionamos el formulario a “lanzar”, y comenzaremos a interactuar con él.



Podremos ir viendo cómo el Recorder va “grabando” nuestras acciones sobre el formulario. Si en un momento dado queremos insertar una comprobación (un Assert), pulsaremos con el botón derecho del ratón sobre el control, y en el menú contextual seleccionaremos la propiedad del mismo sobre la que efectuar la comprobación. De este modo tendremos un método de prueba [Test] que insertar dentro del proyecto de pruebas con NUnit y NUnitForms. El código de la prueba generada quedaría así:



[csharp]
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using NUnit.Framework;
using NUnit.Extensions.Forms;

namespace TestingUITests
{
[TestFixture]
public class Form1Tests
{
[Test]
public void Test()
{

TextBoxTester textBox1 = new TextBoxTester("textBox1");
ButtonTester Form1_button1 = new ButtonTester("button1", "Form1");
LabelTester label1 = new LabelTester("label1");
FormTester Form1 = new FormTester("Form1");

textBox1.Enter("hola");
Form1_button1.Click();
textBox1.Enter("adios");
Form1_button1.Click();
Assert.AreEqual("2", label1.Properties.Text);
Form1.Close();
}

}
}
[/csharp]



Existe también una aproximación bastante interesante a las pruebas del UI en aplicaciones Windows mediante el uso de WF (Windows Workflow Foundation). El proyecto puede encontrarse en Codeproject, y merece la pena echarle un vistazo.


En el caso de las pruebas sobre la UI en aplicaciones web, contamos con frameworks de prueba como Selenium, que incorpora un plugin para Firefox para ayudarnos a crear las pruebas, de forma parecida al Recorder de NUnit. Pero esta es otra historia, que fue contada en otra ocasión ;) .

jueves, 17 de abril de 2008

Introducción a Scrum

Sebastian Chabal y Scrum


La solidez del equipo de rugby, con su líder alerta ante las presiones del entorno es una de las bazas de la metodología de desarrollo Scrum, tal y como refleja la imagen superior. Scrum proporciona un conjunto de reglas para proveer dicha protección y una mayor comunicación entre los miembros del equipo, y recibe precisamente su nombre del de la formación en que se disponen estos jugadores. Está inscrita dentro de las metodologías ágiles, entre ellas Extreme Programming (XP), y sus valores derivan del Manifiesto Ágil.


En cualquier caso, la intención de esta entrada es dar una breve introducción a Scrum, aunque que existen varias muy completas y accesibles que pueden encontrarse al pie del artículo, pero en este caso pretendo estudiarlo desde la perspectiva de la integración de Scrum con Test-Driven Development (TDD) y el Rational Unified Process (RUP).


La definición que para RUP tiene la Wikipedia es:




Un proceso de desarrollo de software y junto con el Lenguaje Unificado de Modelado UML, constituye la metodología estándar más utilizada para el análisis, implementación y documentación de sistemas orientados a objetos.


El RUP no es un sistema con pasos firmemente establecidos, sino un conjunto de metodologías adaptables al contexto y necesidades de cada organización.

Por otro lado, TDD ya es conocido por los lectores del blog, y se trata de una metodología de desarrollo que basa el mismo en la guía mediante pruebas unitarias del software. De este modo, tenemos un proceso de desarrollo, RUP, que consta de cuatro fases (Concepción, Elaboración, Construcción y Transición), unas directrices proporcionadas por Scrum, y una metodología que es la aportada por TDD. ¿Cómo encajar todo esto en una organización en la que está implantado RUP? Lo primero, como ya apuntaba en su día respecto a la implantación de TDD en la empresa, es comenzar por pequeños equipos que actúen como motor de transición para el resto de la organización. Además, a esto se suma que Scrum está especialmente indicado para equipos que consten de 7 a 15 miembros, aproximadamente. Comenzaremos, ya que introdujimos TDD en su día, a hacer lo propio con Scrum, para ir ampliando tanto uno como otro en sucesivas entradas.Ante todo, debemos tener claro que Scrum plantea ciclos de desarrollo de unos 30 días, y define unos roles muy específicos en todo el proceso. Comenzando por los roles, tendremos:

  • Cliente: en efecto, es quien piensas :).

  • Product Owner: muy cercano al cliente, o un miembro de la organización que conozca claramente el producto y los requerimientos asociados al mismo.

  • Scrum Master: similar al jefe de equipo, se encargará de definir tareas, y será el “paraguas” que cubrirá al equipo de desarrollo, evitando que se interfiera en el proceso de desarrollo.

  • Scrum Team: el equipo de desarrollo. A sus miembros se les suele denominar cerdos (pigs). Antes de que nadie se ofenda, diremos que en Scrum hay dos tipos de individuos: los cerdos, que se comprometen con el desarrollo, y las gallinas (chickens), que se involucran, tienen interés en el producto, pero no se implican. La mejor explicación que he encontrado para estos roles es la siguiente tira cómica:



060911-scrumtoon-spanish.jpg






En cuanto a las actividades definidas por Scrum, tenemos:

  • Product Backlog: donde el Product Owner define los requisitos, las nuevas funcionalidades y errores a subsanar.

  • Sprint Planning Meeting: El Product Owner se reúne con el Scrum Master y el Scrum Team. Definen DE FORMA REALISTA, last areas a realizar durante los próximos 30 días.

  • Sprint Backlog: Durante 30 días se desarrolla para conseguir alcanzar los objetivos, definidos en la Sprint Planning Meeting. Diariamente el Scrum Master se reunirá con el Scrum Team (Daily Scrum Meeting), para dar respuesta a tres cuestiones, para cada miembro del equipo:

    • ¿Qué he hecho desde la última reunión?

    • ¿Qué haré hasta la próxima?

    • ¿Existe algún problema que me impida cumplir con las tareas asignadas?






El Scrum Master deberá actuar como paraguas del equipo, evitando que se interfiera en el trabajo. Durante todo el Sprint Backlog no se redefinirán tareas, ni se incorporarán cambios. Al finalizar los 30 días, existirá un entregable. El Product Owner podrá hacer una presentación del mismo a los clientes o directivos de la empresa. Se llevará a cabo otra reunión, de forma retrospectiva, como evaluación del Sprint Backlog, para ver el grado de alcance de los objetivos fijados, y cuáles han sido los logros y problemas encontrados (lecciones aprendidas).

Se volverá a entregar un nuevo paquete de trabajo del Product Backlog, y se comenzará un nuevo ciclo de Sprint Backlog.





En los sucesivas entradas iremos viendo cómo integrar estos ciclos con TDD y, a mayor escala, con RUP en toda la empresa.

Para saber más:



jueves, 3 de abril de 2008

TDD Cheat Sheet

TDD


Hace un par de días hablaba sobre cómo las Cheat Sheets constituyen una ayuda para el usuario y desarrollador al ser prácticamente unas guías de referencia rápida sobre diversas aplicaciones y lenguajes de programación. En esta ocasión traigo una guía de referencia rápida del proceso de Test-Driven Development. Precisamente por ser una metodología sencilla suelen cometerse diversos errores en la adopción de TDD por los equipos de desarrollo, y el objetivo de esta cheat sheet es evitar dichos errores. Para su redacción me he basado en la referencia que Gunjan Doshi preparase para TestDriven.com, adaptándola a las necesidades de un equipo de desarrollo y ampliándola para abarcar desde las referencias sobre qué es una prueba unitaria hasta una introducción a los frameworks de pruebas, como NUnit. Espero que os sea útil. Puede descargarse desde la zona de downloads del blog.

lunes, 31 de marzo de 2008

Pruebas unitarias en la interfaz de usuario

La dificultad de automatizar las pruebas en la interfaz de usuario (UI) es uno de los problemas conocidos de los desarrollos orientados según Test-Driven Development (TDD). Por ello, es muy importante la separación de la lógica de negocio y acceso a datos de la UI ya que, de este modo, dotamos a nuestra aplicación de una mayor independencia respecto a la plataforma en la que deba visualizarla el usuario, y podemos tener una mayor cobertura de código durante las pruebas.


Sin embargo, hay herramientas que pueden facilitarnos la tarea, como Selenium, destinada a probar la UI de aplicaciones web directamente desde el navegador, ya que se instala como un plugin para Firefox, resultando tan útil como lo fue en su día FireBug, el famoso depurador web. También es posible usarlo con Explorer, Safari y Mozilla, aunque para las pruebas de hoy he usado la versión plugin que comentaba antes.


Selenium incorpora dos modos de operación: Núcleo (Core) y Control Remoto (RC). El modo de Control Remoto también proporciona la posibilidad de realizar pruebas en paralelo desde diferentes equipos usando Selenium Grid.


Si instalamos el plugin para Firefox, podemos acceder al mismo a través del menú Herramientas -> Selenium IDE. Desde el mismo podemos crear Suites y Casos de prueba automatizados. Permite simular la interacción del usuario con el sistema, recuperar eventos y objetos; en suma, llevar TDD a uno de los campos de los que había sido excluido sistemáticamente.




Selenium IDE 1
Creación de un caso de prueba mediante el IDE de Selenium

 




Selenium IDE 2
Resultado de la ejecución de la prueba anterior. Vemos cómo falla una de las condiciones.

 


Es posible también acceder a una web a través de la cual podemos ejecutar las pruebas incluidas en las distintas suites que creemos en el IDE.



Selenium en web


 


Así pues, estamos ante una interesante aplicación que podemos descargar desde su web en OpenQA, http://selenium.openqa.org/


 


Selenium IDE

sábado, 29 de marzo de 2008

La implantación de TDD en nuestra empresa

red_2dgreen_2drefactor.png


Que el desarrollo guiado por pruebas, o Test-Driven Development (TDD) es beneficioso para la calidad de nuestro software es algo innegable. Nos permite desarrollar sin basarnos en el depurador para verifica que nuestro software sigue cumpliendo con los requisitos, y facilita la tarea de refactorización del mismo, precisamente gracias a ello, posibilitando así que el código quede más limpio y optimizado. El uso de las pruebas unitarias o de desarrollador no involucra mayor problema pero, ¿cómo incorporamos el proceso de desarrollo guiado por pruebas a nuestro equipo o empresa?


Si nuestra empresa nunca ha realizado un desarrollo basado en pruebas, lo primero que deberemos hacer es formar a los miembros de nuestro equipo adecuadamente. En este sentido, el conocimiento de las herramientas disponibles para la creación y automatización de las pruebas será indispensable, por lo que habrá que enseñar a nuestro equipo cómo usar estas nuevas herramientas y descubrir qué características y metodologías encajan mejor en nuestro propio entorno de trabajo.


Desde el comienzo se hará necesario un seguimiento de la aceptación del proceso por parte del equipo, ya que será vital conocer cómo interiorizan la filosofía de TDD y en qué modo es puesta en práctica. Para conseguirlo, estableceremos pequeños objetivos fácilmente alcanzables, tal vez limitando el alcance de las pruebas a determinados elementos de las aplicaciones, permitiendo así que los programadores se familiaricen lo suficiente con la metodología de TDD antes de abarcar metas más ambiciosas. De esta forma, conseguiremos una mayor interiorización de la misma más rápidamente y, mediante estos pequeños logros, también conseguiremos que el equipo se sienta motivado ante el cambio, reduciendo así una posible resistencia al mismo ya que, como cualquier otro cambio, TDD requiere por parte de nuestro equipo un cambio en los comportamientos adquiridos y el desarrollo de nuevos hábitos, como puede ser el desarrollar código SÓLO cuando existe una prueba que validar. Conviene recordar que tan del equipo son los programadores como los analistas o jefes de proyecto, que deberán, en su totalidad, amoldarse a las nuevas condiciones de trabajo impuestas por la metodología de desarrollo que hemos decidido adoptar.


Una posible hoja de ruta para la adopción de TDD en nuestra empresa podría ser la siguiente:




  1. Formar al equipo.

  2. Estudiar los requerimientos y limitaciones de nuestra organización.

  3. Identificar los parámetros que nos ayuden a comprobar en qué medida se va desarrollando la implantación de TDD.

  4. Establecer pequeñas metas que puedan ser fácilmente alcanzables, para ir incrementando el alcance y dificultad de las mismas de forma progresiva. Por ejemplo, establecer en qué partes del código se establecerán los métodos de prueba, e ir ampliando su alcance.

  5. Delimitar un lapso de tiempo en el que se evaluará la adopción de TDD.

  6. Usar TDD, escribiendo las pruebas siempre antes que el código que deba superarlas.

  7. Comprobar la validez de las pruebas, y la adecuación de las mismas a lo definido en TDD.

  8. Realizar ajustes, en base a la evaluación anterior.

  9. Continuar ampliando el ámbito de actuación de nuestro equipo, abarcando cada vez más código.

  10. Proseguir con la investigación y adopción de las mejores prácticas de desarrollo, y las herramientas más óptimas. Esto implica un reciclaje continuo del equipo, lo que hace que se sienta motivado y proactivo.


Para saber más:

Actualización (8 de abril de 2008): El blog registra una nueva entrada el 3 de abril de 2008 sobre Cheat Sheets, en concreto recogiendo una "hoja de trucos" o guía de Test-Driven Development, disponible para su descarga en formato PDF.

miércoles, 26 de marzo de 2008

Test Driven Development, una introducción

En los días pasados he estado poniendo a prueba un par de plugins para Wordpress que me permitiesen incluir en las entradas presentaciones como la que muestro hoy. Sin embargo, ni el de ThinkFree, que permite mostrar varios tipos de contenido (documentos de Word, de PowerPoint o Excel) en las páginas, pero abriéndolos a pantalla completa, ni el propio de SlideShare (el que han dado en llamar el "Youtube de los Powerpoint"), que si bien es bastante adecuado para lo que pretendía, tiene como problema la tardanza en la conversión de las presentaciones al propio formato de Slideshare (subí ayer, a las 8 de la tarde, una presentación con sólo 12 diapositivas, y hoy, a las 7 de la mañana sigue sin actualizarse).



Así pues, decidido a no dar mi brazo a torcer, he optado por una solución propia. Por un lado, he usado la aplicación gratuita
Authorpoint Lite para convertir la presentación a Flash y, posteriormente, la incluyo en la entrada incrustada dentro de un iframe. Actualización: por motivos de seguridad, no es posible abrir la presentación en el iframe, pero puede descargarse al pie de la entrada y en la zona de descargas del blog.



Como hemos podido ver, muestro una pequeña presentación introductoria al material sobre TDD que estoy preparando. Es algo escueta, pero puede dar una idea aproximada de mis pretensiones a la hora de incluir presentaciones en el blog.

Actualización (8 de abril de 2008):

El blog registra una nueva entrada el 3 de abril de 2008 sobre Cheat Sheets, en concreto recogiendo una "hoja de trucos" o guía de Test-Driven Development, disponible para su descarga en formato PDF.

Actualización (noviembre de 2008):

Tras algunos problemas de acceso a la presentación, habilito el siguiente enlace para descargarla en ZIP.

lunes, 24 de marzo de 2008

ASP.NET MVC Framework

Para todos aquellos que en su día trabajamos con ASP, la llegada de ASP.Net con su clara separación del código de visualización (HTML) respecto al de ejecución (code-behind, escrito en el lenguaje soportado por el CLR que más nos guste) nos supo a verdadera gloria. Sin embargo, después de trabajar durante bastante tiempo con esta arquitectura (versiones 1.1 y 2.0 del .Net Framework), lo que en su día nos pareció la panacea realmente se reveló como un sistema plagado de problemas de desarrollo y mantenimiento. El uso constante del refresco de la página (postbacks) para recuperar datos del servidor, que no llegaba a solucionarse con el uso de AJAX (o ATLAS) y de servicios web, no era el súmmum de la eficiencia. Para dar solución a estos problemas, Microsoft lanzó el pasado diciembre el ASP.NET 3.5 Extensions Preview, destinado al desarrollo web, que incluye entre sus características el soporte para ADO.NET Entity Framework, ADO.NET Data Services, ASP.NET Dynamic Data y ASP.NET MVC. Con este último nos quedaremos en la entrada de hoy.


ASP.NET MVC Framework permite agilizar los desarrollos basados en el patrón de diseño Modelo Vista Controlador, cuyo diagrama de clases sería el siguiente.


MVC


En este patrón, el Modelo constituye la capa de persistencia de la aplicación, es decir, la capa más cercana a dónde y cómo se almacena la información. La Vista, como su nombre indica, es la encargada de la presentación de la aplicación al usuario, brindando al mismo la interfaz de uso correspondiente. Por último, el Controlador es el responsable de determinar la lógica de ejecución a partir de las acciones que se producen en la aplicación.


Entre otras, el uso del ASP.NET MVC aporta las siguientes ventajas:




  • URLs amigables.

  • Control sobre el código de presentación (XHTML puro).

  • Separación de lógica, presentación y control.

  • Como consecuencia de lo anterior, una mayor flexibilidad para la implantación de pruebas unitarias en el software (y facilita las técnicas de desarrollo TDD).

  • Facilita las técnicas de Inversión de Control (IoC).

  • Los componentes existentes pueden ser reemplazados por componentes de terceros.

  • Uso de ASP.NET "clásico" (eliminando postbacks).

  • Integración con VS2008.


Al crear un proyecto ASP.NET MVC, el asistente creará una estructura organizada para el trabajo, basada en la plantilla de proyecto "ASP.NET MVC Web Application" de Visual Studio. Esta plantilla genera una serie de carpetas para almacenar las clases del Modelo (/Models), de la Vista (/Views) y del Controlador (/Controllers).

Una de las características más llamativas del Framework MVC es el mapeo que realiza de las URL a las diversas clases del controlador. Sin efectuar configuración alguna, las direcciones del tipo /xxx/ serán asociadas con la clase del controlador xxxControler. La conversión de los parámetros de la URL a parámetros de entrada del método de la clase del controlador es automática.


Esta extensión del Framework, como ya ocurría, por ejemplo, con la Web Client Sofware Factory, nos permite desarrollar aplicaciones .Net de una forma más cómoda, segura y eficiente.

domingo, 2 de marzo de 2008

Asserts en NUnit

En un post anterior introducía los atributos con que podíamos etiquetar nuestras clases y métodos de prueba para que NUnit pudiese así reconocerlos y usarlos. Hoy veremos cómo podemos determinar si una prueba ha sido superada o no.


Las aserciones (asserts) son la parte central de la prueba en todos los frameworks xUnit. NUnit nos proporciona la clase Assert, que consta de una serie de métodos estáticos que nos permitirán validar si una determinada prueba ha sido superada o no. Hay que tener en cuenta que los métodos de Assert provocan una excepción si la prueba no ha sido superada, por lo que si en nuestro método hacemos varias llamadas a validaciones de Assert, aquellas que estén tras una prueba no superada no serán ejecutadas. Por esto, es conveniente no situar demasiadas validaciones en un único método, o estaríamos ocultando, aunque fuese temporalmente, la existencia de otros errores en la codificación.


Los métodos de la clase Assert pueden agruparse según su funcionalidad en:

Aserciones de igualdad: evalúan si dos argumentos son iguales. Los métodos están sobrecargados para mayor comodidad nuestra, de modo que puedan pasársele los valores a comprobar sin tener que llevar a cabo previamente una operación de boxing. Ejemplos de este tipo de aserción son:


[csharp]Assert.AreEqual( int expected, int actual );
Assert.AreEqual( int expected, int actual, string message );
Assert.AreEqual( int expected, int actual, string message, params object[] parms );
// unos pocos métodos más...
Assert.AreNotEqual( decimal expected, decimal actual );
Assert.AreNotEqual( decimal expected, decimal actual, string message );
Assert.AreNotEqual( decimal expected, decimal actual, string message, params object[] parms );[/csharp]

Aserciones de identidad: comprueban si los dos argumentos están referenciando al mismo objeto.

[csharp]Assert.AreSame( object expected, object actual );
Assert.AreSame( object expected, object actual, string message );
Assert.AreSame( object expected, object actual, string message, params object[] parms );

Assert.AreNotSame( object expected, object actual );
Assert.AreNotSame( object expected, object actual, string message );
Assert.AreNotSame( object expected, object actual, string message, params object[] parms );[/csharp]

También tenemos un método para comprobar si un objeto está contenido en un array o lista:

[csharp]Assert.Contains( object anObject, IList collection );
Assert.Contains( object anObject, IList collection, string message );
Assert.Contains( object anObject, IList collection, string message, params object[] parms );[/csharp]

Aserciones de comparación: nos permiten comprobar si el valor de un parámetro es mayor o menor que el del otro.


[csharp]Assert.Greater( float arg1, float arg2 );
Assert.Greater( float arg1, float arg2, string message );
Assert.Greater( float arg1, float arg2, string message, object[] parms );

Assert.Greater( IComparable arg1, IComparable arg2 );
Assert.Greater( IComparable arg1, IComparable arg2, string message );
Assert.Greater( IComparable arg1, IComparable arg2, string message, object[] parms );

Assert.Less( float arg1, float arg2 );
Assert.Less( float arg1, float arg2, string message );
Assert.Less( float arg1, float arg2, string message, object[] parms );

Assert.Less( IComparable arg1, IComparable arg2 );
Assert.Less( IComparable arg1, IComparable arg2, string message );
Assert.Less( IComparable arg1, IComparable arg2, string message, object[] parms );[/csharp]

Aserciones de tipo: nos permitirán validar si el objeto pasado por argumento pertenece a un tipo de dato determinado:


[csharp]Assert.IsInstanceOfType( Type expected, object actual, string message );
Assert.IsNotInstanceOfType( Type expected, object actual, string message );
Assert.IsAssignableFrom( Type expected, object actual, string message );
Assert.IsNotAssignableFrom( Type expected, object actual, string message );[/csharp]

Pruebas de condición: permiten comprobar si se da una determinada condición en el parámetro que le pasamos. Por ejemplo, si su valor es nulo, verdadero o falso, o si está vacío.


[csharp]Assert.IsTrue( bool condition, string message );
Assert.IsFalse( bool condition, string message );
Assert.IsNull( object anObject, string message );
ssert.IsNotNull( object anObject, string message );
Assert.IsNaN( double aDouble, string message );
Assert.IsEmpty( string aString, string message );
Assert.IsEmpty( ICollection collection, string message );
Assert.IsNotEmpty( string aString, string message );
Assert.IsNotEmpty( ICollection collection, string message );[/csharp]

Métodos de utilidad: Los métodos de utilidad permiten extender nuestro framework de pruebas o cambiar su funcionamiento normal. El primero de ellos es Fail(), y nos permitirá generar “fallos controlados” para crear nuestras propios métodos de aserción, personalizados y específicos para nuestros tests.


[csharp]Assert.Fail();
Assert.Fail( string message );
Assert.Fail( string message, object[] parms );[/csharp]

Por ejemplo, en el siguiente código validamos si un string contiene un valor determinado:

[csharp]public void AssertStringContains( string expected, string actual )
{
AssertStringContains( expected, actual, string.Empty );
}

public void AssertStringContains( string expected, string actual, string message )
{
if ( actual.IndexOf( expected ) > 0 )
Assert.Fail( message );
}[/csharp]

Por otro lado tenemos el método Ignore(). Ignore nos permite ignorar una determinada prueba de forma dinámica. Puede usarse en métodos de [Test], [Setup] o [Fixture Setup], pero los propios creadores de NUnit recomiendan usarlo en casos muy determinados, ya que podemos llevar a un comportamiento algo anárquico en las pruebas, haciendo difícil distinguir qué estamos ejecutando en un determinado momento, y qué no.


Por último, indicar que la clase StringAssert proporciona varios métodos extra para la realización de pruebas sobre strings.


[csharp]StringAssert.Contains( string expected, string actual, string message );
StringAssert.StartsWith( string expected, string actual, string message );
StringAssert.EndsWith( string expected, string actual, string message );
StringAssert.AreEqualIgnoringCase( string expected, string actual, string message );[/csharp]

Los ejemplos de esta entrada han sido tomados de la documentación oficial de NUnit 2.4.6.


Actualización (8 de abril de 2008): 

El blog registra una nueva entrada el 3 de abril de 2008 sobre Cheat Sheets, en concreto recogiendo una "hoja de trucos" o guía de Test-Driven Development, disponible para su descarga en formato PDF.

viernes, 29 de febrero de 2008

Atributos de NUnit 2.x

A la espera de las novedades que introducirá el lanzamiento de NUnit 3.0, vamos a presentar el uso de este unit-testing framework en la versión 2.4.x del mismo.


NUnit se presenta como una herramienta muy útil dentro del marco del desarrollo orientado a pruebas (TDD), permitiéndonos realizar las pruebas unitarias de forma automatizada y cubriendo todos los casos de uso que deban implementar las clases de nuestra aplicación. En el TDD, el flujo normal de desarrollo consiste en la escritura de las pruebas, escribir el código que debe pasarlas y hacer un refactoring para eliminar código duplicado. La escritura de las pruebas y la ejecución de los métodos que deben pasarlas correrá a cargo de NUnit.


El uso de NUnit se basa en el uso de atributos personalizados, que indicarán al framework de NUnit qué clases y qué métodos son los de pruebas, y qué pruebas deben realizarse sobre el código. Los atributos de NUnit en su versión 1.x eran nombrados según las convenciones del .Net Framework, pero esto cambió en la 2.x, usando ahora los atributos personalizados que pasamos a enumerar.


Atributos cuyo ámbito de uso es a nivel de clase:




  • TestFixture: Se usa para indicar que una determinada clase contiene métodos de prueba. Entre las restricciones para la clase están que deberá contar con un constructor por defecto (siendo válido el que proporciona automáticamente .Net) y que debe ser pública para que NUnit pueda acceder a ella para la ejecución de las pruebas.


Atributos cuyo ámbito de uso es a nivel de método:




  • Test: Su uso es indicar que un determinado método es un método de prueba. Entre las restricciones para el método de prueba estarán que no devuelva ningún valor (void) y no reciba parámetros, y que la clase a la que pertenezca esté marcada con el atributo TestFixture.



  • ExpectedException: Indica que el método va a producir una excepción del tipo indicado en el atributo (exactamente ese tipo, no otro distinto, aunque herede del mismo). La prueba se considera superada si al ejecutarlo lanza la excepción esperada.



  • TestFixtureSetUp: Inicializa el entorno de pruebas antes de ejecutarlas, es decir, establece las condiciones necesarias para que las pruebas se realicen en un ambiente idóneo. Se ejecutará antes que cualquier otro método. Sólo puede haber un método marcado con el atributo TestFixtureSetUp dentro de una clase TestFixture.



  • TestFixtureTearDown: Se encarga de restaurar el entorno creado para las pruebas por el método marcado con TestFixtureSetUp. Sólo puede haber un método marcado con este atributo dentro de la clase.



  • Setup: Inicializa y establece el entorno antes de la ejecución de cada prueba, es decir, justo antes de cada método de prueba que se ejecute. Generalmente se encarga de inicializar variables y dejar el entorno “limpio” para la ejecución de la prueba. Sólo puede haber un método marcado como Setup dentro de cada clase de pruebas.



  • TearDown: Su función es restaurar el entorno tras la ejecución de cada prueba unitaria. Sólo puede haber un método marcado como TearDown dentro de cada clase de pruebas.


El plan de ejecución de las pruebas será, por tanto, el siguiente:



Ejecución de las pruebas con NUnit


A nivel de método y clase tenemos los siguientes atributos:




  • Category: Otra opción que tenemos es agrupar las pruebas según categorías, de modo que podamos realizar la ejecución de un determinado bloque de pruebas simplemente indicando la categoría a la que pertenece la prueba. Para ello haremos uso del atributo Category, que puede usarse de forma conjunta a los atributos TestFixture o Test, es decir, a nivel de clase o de método.



  • Explicit: Obliga a indicar durante el proceso de pruebas que se incluya una determinada prueba en el mismo. Es decir, hay que indicar explícitamente que deseamos ejecutar una determinada prueba, siendo ignorada por NUnit en caso contrario.



  • Ignore: Es usado para ignorar una determinada prueba y no incluirla en el plan de pruebas. Al ejecutar NUnit, se marcará con amarillo, indicando que hay código sin probar. La ventaja de esto es que el código estará incluido en el ensamblado, ya que es compilado, pero lo excluimos de las pruebas igual que si todo el código del método o la clase hubiese sido comentado.


En la próxima entrega veremos un ejemplo de clase de pruebas haciendo uso de estos atributos y de otra de las características de NUnit, las aserciones (Asserts), que nos permitirán validar si el resultado esperado en las pruebas coincide con el que nos devuelve nuestro método probado.


Actualización (8 de abril de 2008): 

El blog registra una nueva entrada el 3 de abril de 2008 sobre Cheat Sheets, en concreto recogiendo una "hoja de trucos" o guía de Test-Driven Development, disponible para su descarga en formato PDF.

 

jueves, 28 de febrero de 2008

NUnit 3.0

La Programación Extrema o Extreme Programming (XP), es una metodología ágil de desarrollo basada en una serie de aspectos que permitirían un desarrollo permisivo y adaptable a los cambios de requisitos que se producen habitualmente durante el desarrollo de un proyecto. Una de las características fundamentales de este enfoque es el desarrollo orientado a pruebas (Test-Driven Development, o TDD), en el que las pruebas se suelen escribir antes incluso que el propio código que ha de superarlas. En este aspecto profundizaremos en una próxima entrada del blog, al incluir las pruebas unitarias en el desarrollo de nuestra aplicación con la Web Client Software Factory que introdujimos hace unos días. Sin embargo, el propósito de hoy no es otro que presentar una de las herramientas más usadas a este efecto en los desarrollos con tecnologías Microsoft .Net. Me refiero a NUnit, un framework de pruebas unitarias perteneciente a la familia xUnit, que sigue vigente hoy día, aun a pesar de la inclusión por parte de Microsoft de los proyectos de prueba (Test Projects) en las ediciones Team System de los IDE de desarrollo Visual Studio 2005 y 2008. Entre los motivos en los que me baso para afirmarlo se encuentran el pecuniario (los costes de una licencia de VSTS son mucho más elevados que los de un Visual Studio Professional + NUnit -que es gratuito-, y ya no digamos que los de un SharpDevelop o Eclipse con NUnit, que son nulos) y el de la portabilidad, ya que NUnit está disponible, por ejemplo, para plataformas Linux en las que podríamos estar desarrollando con Mono .


NUnit, en el momento en que escribo estas líneas, está disponible en su versión 2.4.6, que será la que usemos en las próximas entradas relacionadas con el TDD, pero está previsto el lanzamiento de la versión 3.0, que incluirá importantes cambios con respecto a la versión actual. Para empezar, su arquitectura estará basada en plugins, por lo que será mucho más extensible que NUnit 2.4.x, que permite la ampliación de sus funcionalidades mediante la incorporación de addins, pero está muy limitado a este respecto. La ventaja de las aplicaciones que permiten la incorporación de plugins es que, partiendo de una configuración básica, pueden personalizarse para cada usuario en concreto, haciendo la herramienta más útil para el mismo, y más adaptable al cambio.


La segunda característica que incorporará NUnit 3.0 es su arquitectura basada en tres capas: interfaz de usuario, motor de pruebas y framework xUnit.



Capas de NUnit 3.0


Esta división en capas permite que NUnit pueda usarse de diversas formas: mediante su propio inferfaz gráfico o en consola, usando NAnt, por ejemplo, para automatizar pruebas. También que las pruebas sean extensibles a varias plataformas, ya que NUnit 3.0 permitirá la ejecución de pruebas como un proceso separado, dependiendo de la versión del CLR, así como la ejecución distribuida de las pruebas en distintos puntos de una red mediante agentes remotos (Test Agents) . Por último, la capa de framework permite que las pruebas puedan hacerse en diferentes versiones del .Net Framework, en el Mono CLR y con el Compact Framework, en plataformas Linux y Windows, así como entornos de 32 y 64 bits.


Aunque faltan unos meses para poder disfrutar de la nueva versión de NUnit, todo parece apuntar a que la espera merecerá la pena.


Actualización (8 de abril de 2008): 

El blog registra una nueva entrada el 3 de abril de 2008 sobre Cheat Sheets, en concreto recogiendo una "hoja de trucos" o guía de Test-Driven Development, disponible para su descarga en formato PDF.