viernes, 17 de octubre de 2008

Pruebas - Integracion de Aplicaciones

Aunque nuestros desarrolladores de lado del servidor prueben su codigo, y nosotros probemos nuestro codigo (con flex unit, mercury, flexmonkey o lo que queramos usar) el proceso de integracion entre cliente y servidor es necesario probarlo con ambos capas interactuando juntas (no solo por aparte) y de manera continua y automatizada para comprobar cualquier cambio o problema que se pueda encontrar.
Con Flex el problema es que nuestros llamados son asincronimos y no tenemos idea cuando vamos a recibir la informacion de vuelta. Esto hace que nuestros tests usando FlexUnit (la principal unidad de pruebas para flex) pasen efectivamente aunque la respuesta del servidor no sea correcta (esto por la naturaleza sincronica del flexunit) ya que el assert no se ejecuta hasta que se regrese el llamado del servidor y la unica forma de arreglar esto es usando un pequeno hack con un Timer, que la verdad hace el diseno de pruebas complicado, tedioso y dificil de mantener.
En cambio utilizando la unidad de pruebas llamada Fluint tenemos una orientacion completa a llamados asincronimos. La naturaleza de la unidad es esa y falicita las pruebas no solo de llamadas remotas, sino tambien de creacion de componentes, integracion de componentes, etc. Su documentacion aunque no es la mejor es bastante buena y el codigo es abierto. Tiene ademas un Runner de las pruebas que es ejecutable en AIR,  y genera reportes en archivos XML intepretables por parte de alguna herramienta que utilicemos para el continuous integration, como Cruise Control o Hudson
En general Fluint cumple mas alla de mis expectativas ya que su soporte asyncronimo es perfecto para todo lo que ocupamos probar, a diferencia de lo que hacer FlexUnit. Mas adelante quisiera exponer un poco con herramientas de automatizacion de pruebas como Mercury o Flex Monkey que parece ser una excelente opcion open source para esto.
Todo esto como buenas practicas que desarrolladores de Flex deberiamos de tener en nuestro repertorio... Son cosas MUY importantes y que crearan un desarrollo mas fluido y tranquilo. 
Aqui un pequeno y muy BASICO ejemplo para probar llamadas remotas:
/**
* Prueba, invocamos al metodo login de nuestro servicio con
* los parametros 'username y 'password'
* y se crea un responder de tipo TestRespoder que provee Fluint para
* poder saber quien recibira que en nuestro llamado
*/
public function testLoginService():void
{
var responder:IResponder = asyncResponder(
new TestResponder( handleResult, handleFault ) , 3000 );
var token:AsyncToken = remote.getOperation('
login').send("username",
"password");
token.addResponder(responder);
}

/**
* Handle del result de la llamada. Hacemos el Assert.
*/
private function handleResult( data:Object, passThroughData:Object ):void
{
trace(data);
assertNotNull(data);
}

/**
* Handle del fault de la llamada. Inmediatamente despachamos un
* Fail del test.
*/
private function handleFault( info:Object, passThroughData:Object ):void
{
fail("Received fault from Server: " + info);
}