C�mo utilizar NUnit Fecha: 09/Sep/2004 (27/Ago/04)
|
. |
1. INTRODUCCI�N
Lo que hace tan efectiva la TDD es la automatizaci�n de las pruebas de programador, (programmer unit tests) y el hecho de que las herramientas para implementar esta t�cnica son gratis y totalmente funcionales.
NUnit es una de esas herramientas utilizada para escribir y ejecutar pruebas en .NET, NUnit es un framework desarrollado en C# que ofrece las funcionalidades necesarias para implementar pruebas en un proyecto. Adem�s provee una interfaz grafica para ejecutar y administrar las mismas.
El hecho de utilizar TDD implica 3 acciones: escribir las pruebas, escribir el c�digo que debe pasar las pruebas y refactorizar para eliminar el c�digo duplicado.
La primera se lleva a cabo de una manera sencilla y simple utilizando NUnit, NUnit soporta los lenguajes bases de .NET como C#, J#, VB y C++.
2. DESCRIPCION
NUnit es una herramienta que se encarga de analizar ensamblados generados por .NET, interpretar las pruebas inmersas en ellos y ejecutarlas. Utiliza atributos personalizados para interpretar las pruebas y provee adem�s m�todos 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.
NUnit carga en su entorno un ensamblado y cada vez que lo ejecuta, o mejor, ejecuta las pruebas que contiene, lo recarga. Esto es �til porque se pueden tener ciclos de codificaci�n y ejecuci�n de pruebas simult�neamente, as� cada vez que se compile no tiene que volver a cargar el ensamblado al entorno de NUnit si no que este siempre obtiene la �ltima versi�n del mismo.
NUnit ofrece una interface simple que informa si una prueba o un conjunto de pruebas fall�, pas� o fue ignorada.
La �ltima versi�n disponible de NUnit es la 2.2, que se encuentra en estado beta y la ultima versi�n estable es la 2.1, se pueden descargar de: http://www.nunit.org/download.html
3. FUNCIONAMIENTO
NUnit basa su funcionamiento en dos aspectos, el primero es la utilizaci�n de atributos personalizados. Estos atributos le indican al framework de NUnit que debe hacer con determinado m�todo o clase, es decir, estos atributos le indican a NUnit como interpretar y ejecutar las pruebas implementadas en el m�todo o clase.
El segundo son las aserciones, que no son mas que m�todos del framework de NUnit utilizados para comprobar y comparar valores.
3.1 ATRIBUTOS
La versi�n 1x de NUnit utilizaba las convenciones de nombrado del framework de .NET, pero desde la versi�n 2 en adelante NUnit usa atributos personalizados.
Dado que el framework de NUnit no deriva de otra clase o framework, el desarrollador puede elegir el nombre de la prueba a su antojo.
TestFixture
Este atributo se utiliza para indicar que una clase contiene m�todos de prueba. En versiones anteriores para poder utilizar este atributo se deb�a extender (heredar de) la clase TestCase, a partir de la versi�n 2 esto no es necesario, situaci�n que hace mucho m�s flexible el uso del atributo.
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.
Ejemplo:
#using <Nunit.Framework.dll> using namespace System; using namespace NUnit::Framework; namespace NUnitTests { [TestFixture] public __gc class SuccessTests { // ... }; } #include "cppsample.h" namespace NUnitTests { // ... } package NUnit.Tests; import System.*; import NUnit.Framework.TestFixture; <font color = #008000>/** @attribute NUnit.Framework.TestFixture() */ public class SuccessTests { // ... }
Imports System Imports Nunit.Framework Namespace Pruebas <TestFixture()> Public Class PruebasProgramador '... End Class End Namespace
Test
Se utiliza para marcar un m�todo como m�todo de prueba, �ste no debe tener par�metros de entrada y debe retornar void (en el caso de visual Basic ser un sub) as� mismo la clase que lo alberga debe tener marcado el atributo TextFixture.
Ejemplo:
Imports System Imports Nunit.Framework Namespace Pruebas <TestFixture()> Public Class PruebasProgramador <Test()> Public Sub MetodoA() ' ... End Sub End Class End Namespace
TestFixtureSetUp / TestFixtureTearDown
El primero de estos atributos se encarga de crear el ambiente de pruebas antes de ejecutarlas y el segundo se encarga de restaurar el ambiente despu�s de que las pruebas han sido ejecutadas. Van de la mano con los atributos Setup y TearDown, Setup es llamado antes de que se ejecute cualquier prueba. TearDown es llamado despu�s de que una prueba se ejecute.
Una clase marcada con TextFixture solo puede tener un m�todo marcado con TestFixtureSetUp y un solo m�todo marcado con TestFixtureTearDown, si existe mas de un m�todo marcado con estos atributos el proyecto compilara pero no se ejecutaran las pruebas. El orden de ejecuci�n es el siguiente:
ExpectedException
Este atributo como su nombre lo sugiere, tiene como funcionalidad indicar que la ejecuci�n de un m�todo prueba va a lanzar una excepci�n, el atributo tiene como par�metro el tipo de excepci�n que se espera que lance el m�todo, el framework ejecuta la prueba y si se genera una excepci�n del tipo especificado entonces la prueba es exitosa, si por el contrario se genera una excepci�n de tipo diferente al especifico la prueba no lo es. Esto es cierto aun cuando la excepci�n lanzada herede de la excepci�n esperada, es decir la excepci�n debe ser exactamente la especificada en el par�metro del atributo
Ejemplo:
namespace Pruebas { using System; using NUnit.Framework; [TestFixture] public class Pruebas { [Test] [ExpectedException(typeof(InvalidOperationException))] public void GeneraExcepcion() { //... } } }
Imports System Imports Nunit.Framework Namespace Nunit.Tests <TestFixture()> Public Class SuccessTests <Test(), ExpectedException(GetType(Exception))> Public Sub ExpectAnException() ' ... End Sub End Class End Namespace
#using <Nunit.Framework.dll> using namespace System; using namespace NUnit::Framework; namespace NUnitTests { [TestFixture] public __gc class SuccessTests { [Test] [ExpectedException(__typeof(InvalidOperationException))] void ExpectAnException(); }; } #include "cppsample.h" namespace NUnitTests { // ... }
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 versi�n 2 debido al nuevo mecanismo din�mico de ejecuci�n de pruebas del framework (en modo gr�fico se puede seleccionar que pruebas se desean ejecutar utilizando el atributo category, adem�s se pueden agrupar dentro de una estructura marcada como TestFixture). En general es soportada para proveer compatibilidad hacia atr�s.
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 categor�a de pruebas en particular. Ya sea en modo grafico o en modo consola se puede especificar que categor�as se excluyen o incluyen en la ejecuci�n. Cuando se utilizan categor�as, solo las pruebas de la categor�a seleccionada son ejecutadas. Las pruebas incluidas en las categor�as que se excluyen de la ejecuci�n no son reportadas.
Para excluir o incluir determinada categor�a en el modo consola incluya el par�metro /exclude o /include seguido del nombre de la categor�a. En el modo gr�fico existe una pesta�a denominada categor�as.
Es importante anotar que esta funcionalidad solo se encuentra presente en la versi�n 2.2 del producto. Este atributo puede utilizarse junto con TextFixture o Test
Ejemplos:
Imports System Imports Nunit.Framework Namespace Pruebas <TestFixture(), Category("PruebasLargas")> Public Class PruebasLargas1 '... End Class End Namespace
Imports System Imports Nunit.Framework Namespace Pruebas <TestFixture()> Public Class PruebasExitosas <Test(), Category("Corta")> Public Sub PruebaCorta() '... End Sub End Class End Namespace
Explicit
Este atributo ocasiona que una prueba o un Fixture sean ignorados por el programa y no sean ejecutados a menos que sea especificado lo contrario. La prueba o Fixture ser� ejecutada si se selecciona directamente en la interfaz grafica de usuario, si su nombre es especificado en la l�nea de comandos, como el Fixture a ejecutar o si es incluido en una categor�a.
Si una prueba o un Fixture con el atributo Explicit es encontrado durante la ejecuci�n, 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 ejecutar todas las pruebas menos una o unas. Sin embargo las pruebas marcadas con Explicit pueden ser ejecutadas si expl�citamente se le indica al programa que lo haga y esto se hace ya seleccionando la prueba y oprimiendo el bot�n run en el entorno gr�fico o escribi�ndola en la ventana de comandos.
Ejemplos:
namespace Pruebas { using System; using NUnit.Framework; [TestFixture, Explicit] public class PruebaX { //... } }
namespace Pruebas { using System; using NUnit.Framework; [TestFixture] public class PruebaX { [Test, Explicit] public void PruebaExp() { //... } } }
Ignore
Utilizado para indicar que se debe ignorar determinada prueba o Fixture, El programa ve el atributo y no ejecuta la prueba o las 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 moment�neamente, en vez de comentar el m�todo o la clase, ya que de todas maneras va a ser compilada junto con el resto del c�digo pero no ser� tenida encuentra a la hora de ejecutar las pruebas.
Ejemplos:
Imports System Imports Nunit.Framework Namespace Pruebas <TestFixture(), Ignore("Ignore un fixture")> Public Class PruebasX '... End Class End Namespace
Imports System Imports Nunit.Framework Namespace Pruebas <TestFixture()> Public Class PruebasX <Test(), Ignore("Ignore esta prueba")> Public Sub Ignorada() '... End Sub End Class End Namespace
3.2 ASERCIONES
Las aserciones son m�todos est�ticos que la clase assert provee para realizar comparaciones y condiciones de prueba.
Comparaciones
Las aserciones mas utilizadas son las de comparaci�n, �stas reportan tanto el valor esperado como el valor actual. El valor esperado es siempre el primer par�metro en un m�todo assert, por ejemplo:Assert.AreSame(object expected, object actual, string message );
En general se tiene dos m�todos 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 mayor�a de los tipos comunes(int, integer, double, single, string, etc.), por ejemplo
Assert.AreEqual(string expected, string actual, string message );
En una pr�xima versi�n se podr� comparar arreglos.
Es de anotar que los m�todos 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� );
Condiciones de Prueba
Los m�todos que eval�an una condici�n se denominan de acuerdo a la condici�n. El valor a probar es el primer argumento y opcionalmente un mensaje como segundo.
Ejemplo:
Assert.IsTrue( bool condicion ); Assert.IsTrue( bool condicion, string mensaje ); Assert.IsFalse( bool condicion); Assert.IsFalse( bool condicion, string mensaje ); Assert.IsNull( object unObjecto ); Assert.IsNull( object unObjecto, string mensaje ); Assert.IsNotNull( object unObjeto ); Assert.IsNotNull( object unObjeto, string mensaje );
Por ultimo tenemos el m�todo Assert.Fail que es utilizado para generar fallos que no son considerados por los otros m�todos.
4. UTILIZACI�N
4.1 INTERFACES
NUnit provee dos interfaces de usuario, la interfaz gr�fica y la interfaz de consola. Ambas pueden ser instanciadas desde la l�nea de comandos y la gr�fica se puede iniciar tambi�n haciendo doble clic sobre el icono en el escritorio.
Interfaz Gr�fica
Esta interface puede ejecutarse con o sin un nombre de ensamblado desde la ventana de comandos, en el caso que no se especifique ning�n ensamblado la aplicaci�n carga el ultimo ensamblado cargado.
� Para evitar este comportamiento se debe escribir: nunit-gui /noload, por el contrario si desea especificar un ensamblado o nombre de proyecto desde la l�nea de comandos escriba:
nunit-gui [nombreEnsamblado]
� Tambi�n puede abrir un proyecto de VisualStudio .NET:
nunit-gui [Proyecto]
� Para especificar un Fixture especifico de un ensamblado:
nunit.gui /fixture: [fixture] [ensamblado]
� Normalmente la GUI carga un ensamblado y entonces espera que el usuario le indique que ejecute las pruebas seleccionadas, si quiere que las pruebas se ejecuten inmediatamente teclee esto:
nunit-gui [ensamblado] /run
� Para especificar que configuraci�n desea cargar (debug/release) teclee:
nunit-gui [Provecto Visual Studio] /config: [configuracion]
La GUI no permite cargar mas de un ensamblado simult�neamente, para esto se debe cargar la soluci�n completa.
� Para obtener ayuda teclee:
nunit-gui /? � nunit-gui /help
Si desea hacer todo esto directamente en la interfaz grafica simplemente cargue el ensamblado y seleccione el Fixture o la prueba que desea ejecutar, o interactu� con el correspondiente men�
Interfaz Consola
El programa NUnit en modo consola no es agregado autom�ticamente al path del sistema as� que se debe hacer manualmente (nota al final del documento).
Esta interfaz provee algunas opciones adicionales, por ejemplo esta interface siempre crea una representaci�n XML de los resultados llamada �TestResult.xml�, la cual es generada en el direcorio de trabajo.
� A diferencia del modo grafico en la consola siempre se carga el ensamblado y se ejecutan las pruebas autom�ticamente:
nunit-console [ensamblado]
Donde [ensamblado] puede ser un ensamblado, un proyecto de VS.NET o un proyecto de NUnit.
� Para ejecutar solo un Fixture del ensamblado teclee:
nunit.console /fixture: [fixture] [ensamblado]
� Para especificar pruebas con categor�as a incluir o excluir teclee:
nunit-console [ensamblado] /include: [categor�a de pruebas]
nunit-console [ensamblado] /exclude: [categoria de pruebas]
� Es de anotar que include ejecuta solo las pruebas especificadas dentro de la categor�a, mientras que exclude como es l�gico ejecuta todas las pruebas menos las especificadas en la cl�usula. Por otro lado es posible utilizar estos comandos especificando varias categor�as, para hacer esto se debe separa las categor�as por comas.
Si desea guardar los resultados en un archivo de texto lo puede hacer de la siguiente manera:
nunit.console /out: [archivo] (version 2.2)
� Tambi�n lo puede hacer con el archivo de error generado por NUnit:
nunit-console nunit.tests.dll /err: [archivo] (version 2.2)
� Si desea especificar el nombre del archivo xml resultado de las pruebas teclee:
nunit-console /xml:[nombre.xml] [ensamblado]
� Para especificar la configuraci�n a ejecutar teclee:
nunit-console [ensamblado] /config: [Debug/Release]
Tenga en cuenta que esta opci�n no tiene efecto cuando se carga un ensamblado directamente.
� Para ejecutar las pruebas de varios ensamblados separe el nombre de estos con espacios:
nunit-console [ensamblado1] [ensamblado2 ] [ensamblado3]
Se pueden especificar multiples ensamblados pero no multiples proyectos de VS.Net o de NUnit
Otras opciones:
/wait le indica a NUnit que espere la entrada de usuario antes de salir.
/xmlconsole despliega xml puro en la consola, esto es �til cuando se esta depurando
4.2 IMPLEMENTANDO UNA PRUEBA
Mira en la siguiente pagina el ejemplo creado por la gente de NUnit. (he hecho algunos comentarios para adaptar el ejemplo a la versiones nuevas)
NOTA: Para configurar el path del sistema haga lo siguiente:
Clic derecho a Mi PC � propiedades � opciones avanzadas - variables de entorno � variables del sistema. Seleccione path y de clic en modificar, en el campo valor agregue esto al final: [; c:\Archivos de Programa\NUnit V2.1\bin] (sin los corchetes) y por ultimo acepte los cambios.
Ejemplo. Supongamos que hemos escrito una aplicaci�n bancaria y que tenemos una clase de dominio b�sica de Cuenta bancaria (Account). Account soporta operaciones para dep�sito (deposit), retiro (withdraw) y transferencia (transfer) de fondos. La clase ser�a algo similar a esto:
namespace bank { public class Account { private float balance; public void Deposit(float amount) { balance+=amount; } public void Withdraw(float amount) { balance-=amount; } public void TransferFunds(Account destination, float amount) { } public float Balance { get{ return balance;} } } }
Ahora vamos a escribir una prueba para esta clase - AccountTest. El primer m�todo que probaremos ser� transferencia de fondos (TransferFunds).
namespace bank { using NUnit.Framework; [TestFixture] public class AccountTest { [Test] public void TransferFunds() { Account source = new Account(); source.Deposit(200.00F); Account destination = new Account(); destination.Deposit(150.00F); source.TransferFunds(destination, 100.00F); Assertion.AssertEquals(250.00F, destination.Balance); Assertion.AssertEquals(100.00F, source.Balance); } } }
Lo primero que se nota en esta clase es que posee un atributo asociado a ella llamado [TestFixture] � este es la forma de indicar que la clase contiene c�digo de prueba. Esta clase es p�blica (public) y adem�s cuenta con un constructor (el que provee el framework).
El �nico m�todo en la clase TransferFunds (Transferencia de fondos), posee el atributo [Test], esto indica que el m�todo es de prueba. Los m�todos de prueba deben retornar siempre void y no recibir par�metros. En nuestro m�todo de prueba hacemos las inicializaciones usuales de los objetos de prueba necesarios, ejecutamos el m�todo de negocio a ser probado y comprobamos el estado del objeto de negocio. La clase Assertion (Assert) define una colecci�n de m�todos usados para comprobar las condiciones posteriores a la ejecuci�n y en nuestro ejemplo usamos el m�todo AssertEquals (Assert.areEquals() en las nuevas versiones) para asegurarnos que luego de la transferencia, ambas cuentas posean los saldos correctos (existen varias sobrecargas a este m�todo, la versi�n que fue usada en este ejemplo posee los siguientes par�metros: el primer par�metro es un valor esperado y el segundo es el valor almacenado en el objeto).
Compila y ejecuta este ejemplo. Asumamos que compilaste tu clase de prueba como bank.dll. Ejecuta la GUI de NUnit (el instalador habr� creado un acceso directo en tu escritorio y en la carpeta Archivos de Programa), luego de haber iniciado el GUI, selecciona File�Open ,menu item, despl�zate hacia la ubicaci�n de tu archivo bank.dll y selecci�nalo en el cuadro de di�logo �Open�. Cuando la librer�a bank.dll se haya cargado, ver�s una estructura de �rbol para la prueba en el panel izquierdo y una colecci�n de paneles de estado a la derecha. Haz click en el bot�n Run, la barra de estado y el nodo TransferFunds en el �rbol de prueba se tornar�n rojos � nuestra prueba ha fallado. El panel �Errors and Failures� mostrar� el siguiente mensaje � �TransferFunds : expected <250> but was <150>� y el panel de stack trace justo abajo reportar� en que lugar en el c�digo de prueba ocurri� el error- �at bank.AccountTest.TransferFunds() in C:\nunit\BankSampleTests\AccountTest.cs:line 17�
Ese es un comportamiento esperado, la prueba ha fallado debido a que no hemos implementado el m�todo TransferFunds a�n. Ahora hag�moslo funcionar. No cierres el GUI, vuelve a tu IDE y corrige el c�digo, c�mbialo as�:
public void TransferFunds(Account destination, float amount) { destination.Deposit(amount); Withdraw(amount); }
Ahora recompila tu c�digo y haz click en el bot�n run en la GUI nuevamente � la barra de estado y el �rbol de pruebas se tornar�n verdes. (Nota como el GUI ha recargado el assembly autom�ticamente); mantendremos el GUI abierto todo el tiempo y continuaremos trabajando con nuestro c�digo en el IDE y escribiremos m�s pruebas.
Ahora a�adiremos algo de control de errores al c�digo de Account. Estamos agregando el requerimiento de saldo m�nimo a la cuenta para estar seguros de que los bancos contin�en haciendo su dinero obligando a mantener un saldo m�nimo. A�adiremos la propiedad de saldo m�nimo a nuestra clase Account.
private float minimumBalance = 10.00F; public float MinimumBalance { get{ return minimumBalance;} }
Ahora usaremos una excepci�n para indicar la falta de fondos:
namespace bank { using System; public class InsufficientFundsException : ApplicationException { } }
Agrega ahora un nuevo m�todo de prueba a la clase AccountTest:
[Test] [ExpectedException(typeof(InsufficientFundsException))] public void TransferWithInsufficientFunds() { Account source = new Account(); source.Deposit(200.00F); Account destination = new Account(); destination.Deposit(150.00F); source.TransferFunds(destination, 300.00F); }
Este m�todo de prueba adem�s del atributo [Test] posee otro llamado [ExpectedException] - esta es la forma de indicar que el c�digo de prueba est� esperando una excepci�n de cierto tipo; si tal excepci�n no ocurre durante la ejecuci�n � la prueba fallar�. Compila tu c�digo y regresa a la GUI. Mientras compilabas tu c�digo de prueba, la GUI se debi� tornar de color gris y habr� colapsado el �rbol como si las pruebas no hubiesen sido ejecutadas a�n (la GUI espera por cambios hechos en los assemblies de prueba y se actualiza a si misma cuando la estructura del �rbol de prueba cambia � Ej.: cuando se ha agregado una nueva prueba). Haz click en el bot�n Run � ahora tenemos una barra de estado roja nuevamente. Tenemos la misma falla: �TransferWithInsufficentFunds : InsufficientFundsException was expected�. Corrijamos nuestro c�digo de Account nuevamente, modifiquemos el m�todo TransferFunds de la siguiente forma:
public void TransferFunds(Account destination, float amount) { destination.Deposit(amount); if(balance-amount<minimumBalance) throw new InsufficientFundsException(); Withdraw(amount); }
Compila y ejecuta las pruebas � ver�s una barra verde. La prueba fue exitosa! Pero espera, mirando al c�digo que hemos escrito nos podemos dar cuenta que el banco podr�a estar perdiendo dinero en cada operaci�n fallida de Transferencia de fondos. Escribamos una prueba para confirmar nuestra sospecha. A�ade este m�todo de prueba:
[Test] public void TransferWithInsufficientFundsAtomicity() { Account source = new Account(); source.Deposit(200.00F); Account destination = new Account(); destination.Deposit(150.00F); try { source.TransferFunds(destination, 300.00F); } catch(InsufficientFundsException expected) { } Assertion.AssertEquals(200.00F,source.Balance); Assertion.AssertEquals(150.00F,destination.Balance); }
Estamos probando la propiedad transaccional de nuestro m�todo de negocio � todas las operaciones han sido exitosas o ninguna. Compila y ejecuta � Ver�s una barra roja. Veamos, hemos obtenido $300.00 de una manera muy f�cil (D�j� vu de 1999.com?) � la cuenta de origen tiene el saldo correcto de $150.00 pero la cuenta de destino muestra: $450.00. �C�mo corregimos esto?. Podemos simplemente mover la comprobaci�n de saldo m�nimo antes de las transacciones:
public void TransferFunds(Account destination, float amount) { if(balance-amount<minimumBalance) throw new InsufficientFundsException(); destination.Deposit(amount); Withdraw(amount); }
�Qu� tal si el m�todo de retiro Withdraw() lanza otra excepci�n? �Deber�amos ejecutar una transacci�n de compensaci�n en el bloque del catch o confiar en nuestro transaction manager para restaurar el estado de los objetos? Necesitamos contestar estar preguntas en cierto punto, pero no ahora; pero que hacemos con la prueba fallida mientras tanto � �Quitarla? Una mejor manera es ignorarla temporalmente, a�ade el siguiente atributo a tu m�todo de prueba:
[Test] [Ignore("Se necesita decidir como implementar el manejo transaccional en la aplicaci�n")] public void TransferWithInsufficientFundsAtomicity() { el mismo c�digo}
Compila y ejecuta � Ver�s una barra amarilla. Haz click en la vi�eta �Tests Not Run� y ver�s: bank.AccountTest.TransferWithInsufficientFundsAtomicity() en la lista con la raz�n por la cual la prueba es ignorada.
Al ver nuestro c�digo de prueba nos damos cuenta que se puede hacer algo de refactorizaci�n. Todos los m�todos comparten un conjunto com�n de objetos de prueba. Extraigamos el c�digo de inicializaci�n a un m�todo de SetUp y reus�moslo en todas nuestras pruebas. La versi�n refactorizada de nuestra clase de prueba ser�a:
namespace bank { using System; using NUnit.Framework; [TestFixture] public class AccountTest { Account source; Account destination; [SetUp] public void Init() { source = new Account(); source.Deposit(200.00F); destination = new Account(); destination.Deposit(150.00F); } [Test] public void TransferFunds() { source.TransferFunds(destination, 100.00f); Assertion.AssertEquals(250.00F, destination.Balance); Assertion.AssertEquals(100.00F, source.Balance); } [Test] [ExpectedException(typeof(InsufficientFundsException))] public void TransferWithInsufficientFunds() { source.TransferFunds(destination, 300.00F); } [Test] [Ignore("Se necesita decidir como implementar el manejo transaccional en la aplicaci�n ")] public void TransferWithInsufficientFundsAtomicity() { try { source.TransferFunds(destination, 300.00F); } catch(InsufficientFundsException expected) { } Assertion.AssertEquals(200.00F,source.Balance); Assertion.AssertEquals(150.00F,destination.Balance); } } }
Nota que el m�todo Init tiene el c�digo com�n de inicializaci�n, posee tipo de retorno void, sin par�metros, y est� marcado con el atributo [SetUp]. Compila y ejecuta- vas a ver la misma barra amarilla!
Es de anotar que NUnit que puedes hacer debug asociando NUnit al proceso de depuraci�n de Visual Studio, de esta manera es posible ejecutar las pruebas y hacer el seguimiento al programa al mismo tiempo. Para hacer esto inicie NUnit, en VisualStudio de clic en el men� herramientas -proceso de depuraci�n y seleccione NUnit, a continuaci�n puede trabajar con todas las facilidades de debug que proporciona el IDE. Por ultimo tenga en cuenta que cada vez que recompile el c�digo tendr� que volver a asociar NUnit al IDE.