Sunteți pe pagina 1din 20

Tutorial NUNIT

Tutorial de NUnit

Autor: Carlos Hidalgo Lache 1


Tutorial NUNIT

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.

Autor: Carlos Hidalgo Lache 2


Tutorial NUNIT

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


'...

Autor: Carlos Hidalgo Lache 3


Tutorial NUNIT

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:

Autor: Carlos Hidalgo Lache 4


Tutorial NUNIT

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()
{
//...
}
}

Autor: Carlos Hidalgo Lache 5


Tutorial NUNIT

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

Autor: Carlos Hidalgo Lache 6


Tutorial NUNIT

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,

Autor: Carlos Hidalgo Lache 7


Tutorial NUNIT

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()
{
//...
}
}
}

Autor: Carlos Hidalgo Lache 8


Tutorial NUNIT

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 );

Autor: Carlos Hidalgo Lache 9


Tutorial NUNIT

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.

Autor: Carlos Hidalgo Lache 10


Tutorial NUNIT

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

Autor: Carlos Hidalgo Lache 11


Tutorial NUNIT

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

Autor: Carlos Hidalgo Lache 12


Tutorial NUNIT

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).

Autor: Carlos Hidalgo Lache 13


Tutorial NUNIT

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

Autor: Carlos Hidalgo Lache 14


Tutorial NUNIT

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:

Autor: Carlos Hidalgo Lache 15


Tutorial NUNIT

[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);

Autor: Carlos Hidalgo Lache 16


Tutorial NUNIT

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

Autor: Carlos Hidalgo Lache 17


Tutorial NUNIT

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)

Autor: Carlos Hidalgo Lache 18


Tutorial NUNIT

{
}

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.

Ejemplos de Ejecución de NUNIT

Autor: Carlos Hidalgo Lache 19


Tutorial NUNIT

Nota: En caso se este usando Visual Studio 2003, deberás usar el NUNIT para Framework 1.0 y si estas
usando VS .2005 entonces usaras el NUNIT para Framework 2.0

Autor: Carlos Hidalgo Lache 20

S-ar putea să vă placă și