domingo, 9 de agosto de 2009

Flex Unit 4

Recientemente salió al aire Flex Unit 4 (versión Beta en este momento). Esta versión incorpora muchas mejoras, incluyendo mucha funcionalidad incorporada de la libreria para pruebas Fluint, quien le dono muchas mejoras a la misma, sobre todo en el manejo asincronomo.
Debemos recordar que en Flex/Flash estamos dentro de un ambiente asincronimo, esto es: hacemos el llamado a una función pero no sabemos cuando se hara devolvera el llamado a la función. Esto ya que el Flash Player no soporta multi hilos y al hacer uso de ciertos recursos que no tenemos en realidad una idea clara de cuanto va a durar en responder (llamado al servidor, cargar una pelicula, etc) puede hacer que la aplicación termine pegandose y la experiencia de usuario sea demasiado desagradable.
Una de las nuevas caracteristicas incorporadas en esta versión es el uso de metadatas. Esta es una caracteristica utilizada en Flex sobre todo cuando marcamos una propiedad como [Bindable]. Mucha gente no esta al tanto que en Actionscript 3 uno puede crear sus propias metadatas y utilizarlas como quieran dentro de su aplicación, lo cual a mi gusto es demasiado elegante.
Otra nueva caracteristica es que ya no se hace uso de la herencia (para crear nuevos tests y suites), ahora se usan metodos estaticos al estar utilizando metadatas. Ademas podemos ejecutar nuestros tests con distintos Runners (Flex Unit, Fluint, air, etc) que nos brindaran distintas caracteristicas de acuerdo a nuestras necesidades.
A continuacion unos pocos ejemplos de algunos principios. Espero poder agregar mas con el tiempo.

Creación de Suites:
Los suites son un conjunto de tests. Podemos tener dentro de un suite multiples tests.

package tests
{
[Suite]
[RunWith("org.flexunit.runners.Suite")]
public class DelegatesTestSuite
{
//Tests se declaran como propiedades
public var test1:MiClaseTest;
}
}

Creando un Test con un delegate:

package tests
{
public class MiClaseTest
{
//Metodo asincronomo:
//Marcamos el metodo como test y lo colocamos como primero
//en la lista. Ademas le decimos que espere al menos 3500 ms
//para que nos devuelvan algun valor
[Test (async, timeout="3500",order=1)]
public function loginUser():void
{
var user:User = new User()
user.username = "user2";
user.password = "123xyz";

var delegate:UserDelegate = new UserDelegate();
var responder:IResponder = Async.asyncResponder(this, new
TestResponder(onLoginUserComplete, onLoginUserFault), 3000);
}

//Este es el handler que recibira elresultado del
//servidor.
//@param event ResultEvent del servidor.
//@param token, es el objeto inicial que pasamos en el llamado
private function onLoginUserComplete(event:Object, token:Object):void
{
Assert.assertTrue(event.result.authenticated);
}

private function onInsertUserFail(event:FaultEvent, token:Object):void
{
Assert.fail('Error loading user: ' + event.fault);
}
}
}

Creando Teorias:

Y que es esto? Es un nuevo concepto (al menos en el mundo de testing en Flex) Lo que nos dice es que si creemos que algo va a ejecutarse correctamente, tiene que ejecutarse correctamente con cualquier informacion que le sea pasada como parametro, por ejemplo, si debo encontrar que el valor absoluto de un numero va a ser siempre positivo, la teoria me dice que cualquier numero que le pase, va a ser mayor a 0. Entonces en mi test puedo poner un numero infinto de numeros a probar, solo que nosotros no tenemos tanto tiempo como para eso, entonces escogemos un conjunto finito de valores a probar y con ese conjunto validamos nuestra teoria.

Primero tengo que marcar la clase como que tiene una teoria, para que pueda ser procesada con el metadata [RunWith]

package tests
{
[RunWith("org.flexunit.experimental.theories.Theories")]
public class MiClaseTest
{
...
Creando un sets de datos para probar:
Ocupo 2 metadatas [ArrayElementType] utilizado en mxml para especificar el tipo de dato dentro de una coleccion y el metadata [DataPoints] que marca nuestros set como un conjunto para probar.

[DataPoints]
[ArrayElementType("Object")]
public static var usuariosValidos:Array = [
{username:"user1",password:"123xyz"},
{username:"user2",password:"344112"},
{username:"user3",password:"o5ii33"}
];
Creacion de un test con teoria:
Marcamos el metodo conel metadata [Test] y el metadata [Theroy]
[Theory]

[Test(async,timeout="10000")]
public function validUsers(usuarios:Object):void
{
var delegate:UserDelegate = new UserDelegate();
var responder:IResponder = Async.asyncResponder(this, new
TestResponder(onUserLoginComplete, onUserLoginFail), 2500);

delegate.authUser(usuarios.username, usuarios.password);
}

Esto hace que el test se ejecute la cantidad de datos que tengamos dentro de nuestro datapoint, en este caso se ejecutara automaicamente 3 veces.
Esto verdaderamente facilitara nuestro desarrollo en pruebas y nos permitira asegurarnos que podamos testear mejor nuestra aplicacion con menor esfuerzo

Otros Recursos
Introduccion (mejor link que he visto)
Excelente Tutorial
Pruebas Integracion
Importancia Pruebas y Feedback

2 comentarios:

ulises dijo...

Help
Estoy tratando de porbar el delegate y tengo problemas mi codigo es el siguiente

var empleado:Empleado = new Empleado("admin","admin");
var responder:IResponder = Async.asyncResponder(this, new
Responder(onLoginUserComplete, onLoginUserFault),3000);

var delegate:LoginDelegate = new LoginDelegate(responder);
delegate.login(empleado);

y el error que me marca es el siguiente

C0007E: RemoteObject not found for loginService

public function LoginDelegate( responder:IResponder ) {this.responder = responder;
this.service = ServiceLocator.getInstance().getRemoteObject("loginService");
}
el metodo loginService si existe y mi aplicacion asi fucniona bien, solamente en el test falla, espero puedas ayudarme, gracias

Ivan dijo...

Hola! Estas usando el servicelocator que trae cairngorm? Si es asi, debes de hacer la carga del mismo como lo haces en tu aplicacion:

<service:ServiceLocator/>

o como sea que lo llames dentro de tu aplicacion, esto para cargar la lista de remote objects y que pueda ser accesado por tu delegate.
Pon el tag de arriba desde el runner donde corres tus tests...
Saludos