¡La versión 2.0 de Play ya está lista! Ayúdanos a traducir la documentación de la útlima versión y sigue nuestro progreso.

Manuales, tutoriales & referencias

Consulte

Contenidos

Elija la versión

Buscar

Busque con google

Libros

Completando las pruebas de la aplicación

Ya hemos terminado el sistema de blog que queríamos crear en esta guía. Sin embargo el proyecto en sí no está terminado aún. Para estar totalmente seguros de nuestro código necesitamos agregar más pruebas al proyecto.

Por supuesto nosotros ya hemos escrito pruebas unitarias con el fin de probar la funcionalidad de la capa de modelo de yabe. Y es genial, ya que garantizará que la parte principal del sistema de blog está bien probado. Pero una aplicación web no se basa sólamente en el ‘modelo’. Necesitamos garantizar que la interfaz web funciona correctamente. Es decir, que necesitamos probar la capa del controlador de nuestro sistema de blogs. Pero también necesitamos probar la interfaz de usuario en sí, como por ejemplo, nuestro código JavaScript.

Probando la capa del controlador

Play provee una forma de probar directamente la capa del controlador de la aplicación usando JUnit. A estas pruebas se las conoce con el nombre de ‘Pruebas Funcionales’, ya que se utilizan para probar la funcionalidad completa de la aplicación web.

Básicamente una prueba funcional llama al ActionInvoker de Play directamente, simulando una petición HTTP. De manera tal que le especificamos un método HTTP, una URI y parámetros HTTP. Entonces Play resolverá la ruta determinando el controlador al cual derivar la petición HTTP, invocará la acción correspondiente y devuelverá la respuesta. Luego podrás analizar el resultado para verificar que el contenido de la respuesta sea el esperado.

Vamos a escribir nuestra primera prueba funcional. Abra el archivo con la prueba unitaria que Play crea por defecto en yabe/test/ApplicationTest.java:

import org.junit.*;
import play.test.*;
import play.mvc.*;
import play.mvc.Http.*;
import models.*;
 
public class ApplicationTest extends FunctionalTest {
 
    @Test
    public void testThatIndexPageWorks() {
        Response response = GET("/");
        assertIsOk(response);
        assertContentType("text/html", response);
        assertCharset("utf-8", response);
    }
    
}

Por el momento, se ve muy similar a una prueba JUnit estándar. Note que usamos la super clase FunctionalTest de Play con el fin de obtener varios métodos súmamente útiles a la hora de trabajar con pruebas funcionales.. Esta prueba se ejecuta correctamente y sólo verifica que la página de inicio (home) de la aplicación (normalmente el URL /) devuelve una respuesta HTML con código de estado ‘200 OK’.

Ahora revisaremos que la seguridad del área de administración funcione correctamente. Agregue esta nueva prueba al archivo ApplicationTest.java:

…
@Test
public void testAdminSecurity() {
    Response response = GET("/admin");
    assertStatus(302, response);
    assertHeaderEquals("Location", "/login", response);
}
…

Ejecute la aplicación yabe en modo de prueba usando el comando play test, abra http://localhost:9000/@tests, seleccione el caso de prueba ApplicationTest.java y ejecútelo.

¿Se muestra en color verde?

Bien, podríamos continuar probando todas las funcionalidades de la aplicación de esta forma, pero no es la mejor manera de probar una aplicación web basada en HTML. Como nuestro sistema de blog está destinado a ser ejecutado en un navegador web, sería mejor probarlo directamente en un navegador web de verdad. Y esto es exactamente lo que hacen las ‘pruebas Selenium’ o ‘pruebas de aceptación’ de Play.

De todas, este tipo de ‘Pruebas Funcionales’ basadas en Junit resultan de gran utilidad, especialmente para probar Servicios Web que devuelven respuestas que no son HTML, tales como JSON o XML sobre HTTP.

Escribiendo pruebas Selenium

Selenium es una herramienta de pruebas diseñada específicamente para probar aplicaciones web. Lo interesante aquí es que Selenium permite ejecutar la suite de pruebas directamente en cualquier navegador existente. Como no utiliza ningun ‘navegador simulado’, usted puede estar seguro de que lo que está probando es lo que los usuarios usarán.

Normalmente, una suite de prueba Selenium se escribe en un archivo HTML. La sintaxis HTML que requiere Selenium es un poco tediosa de escribir (formateado usando una tabla HTML). La buena noticia es que Play le ayuda a generarla usando el sistema de plantillas de Play y un conjunto de tags que soportan una sintaxis simplificada para trabajar con Selenium. Un efecto secundario interesante de usar plantillas es que usted ya no está atado a ‘escenarios estáticos’ y puede usar el poder de las plantillas de Play (bloques condicionales, ciclos, etc) para escribir pruebas más complicadas.

Sin embargo, todavía puede utilizar la sintaxis HTML normal de Selenium en la plantilla y olvidarse de los tags específicos de Selenium provistos por Play si así lo desea. Este enfoque puede ser muy útil si utiliza alguna de las diversas herramientas de Selenium que generan los escenarios de prueba por usted, como por ejemplo Selenium IDE.

La suite de prueba por defecto de una aplicación Play recién creada ya contiene una prueba Selenium. Abra el archivo yabe/test/Application.test.html:

*{ You can use plain Selenium commands using the selenium tag }*
 
#{selenium}
    // Open the home page, and check that no error occurred
    open('/')
    waitForPageToLoad(1000)
    assertNotTitle('Application error')
#{/selenium}

Esta prueba debería ejecutarse sin ningún problema con la aplicación yabe. Tan sólo abre la página de inicio y verifica que el contenido de la página no incluya el texto ‘Application error’.

No obstante, como cualquier prueba compleja, necesita configurar un conjunto de datos conocidos de antemano antes de probarla on un explorador web. Por supuesto reutilizaremos el concepto de fixture y el archivo yabe/test/data.yml que usamos anteriormente. Para importar estos datos antes de ejecutar la suite de prueba, sólo utilice el tag #{fixture /}:

#{fixture delete:'all', loadModels:'data.yml' /}
 
#{selenium}
    // Open the home page, and check that no error occurred
    open('/')
    waitForPageToLoad(1000)
    assertNotTitle('Application error')
#{/selenium}

Otro aspecto importante que debe verificar es que tengamos una sesión de usuario limpia al inicio de la prueba. Dado que la sesión se almacena en un cookie temporal del navegador, existe la posibilidad de que mantenga la misma sesión durante dos ejecuciones de prueba sucesivas.

Así que vamos a empezar nuestra prueba con un comando especial:

#{fixture delete:'all', loadModels:'data.yml' /}
 
#{selenium}
    clearSession()
 
    // Open the home page, and check that no error occurred
    open('/')
    waitForPageToLoad(1000)
    assertNotTitle('Application error')
#{/selenium}

Ejecútela para estar seguros de que no hay errores. Debería mostrarse en color verde.

Ahora podemos escribir una prueba más específica. Abrir la página de inicio y revisar que los posts por defecto están presentes:

#{fixture delete:'all', loadModels:'data.yml' /}
 
#{selenium 'Check home page'}
    clearSession()
 
    // Open the home page
    open('/')
 
    // Check that the front post is present
    assertTextPresent('About the model layer')
    assertTextPresent('by Bob, 14 Jun 09')
    assertTextPresent('2 comments , latest by Guest')
    assertTextPresent('It is the domain-specific representation')
 
    // Check older posts
    assertTextPresent('The MVC application')
    assertTextPresent('Just a test of YABE')
#{/selenium}

En este caso estamos usando la sintaxis estándar de Selenium, llamada Selenese.

Ejecútela (puede ejecutarla en una ventana diferente sólo con abrir el enlace de prueba en una ventana nueva).

Ahora probaremos el formulario de comentarios. Sólo agregue un nuevo tag #{selenium /} a la plantilla:

#{selenium 'Test comments'}
 
    // Click on 'The MVC application post'
    clickAndWait('link=The MVC application')
    assertTextPresent('The MVC application')
    assertTextPresent('no comments')
    
    // Post a new comment
    type('content', 'Hello')
    clickAndWait('css=input[type=submit]')
    
    // Should get an error
    assertTextPresent('no comments')
    assertTextPresent('Author is required')
    type('author', 'Me')
    clickAndWait('css=input[type=submit]')
    
    // Check
    assertTextPresent('Thanks for posting Me')
    assertTextPresent('1 comment')
    assertTextPresent('Hello')
#{/selenium}

Y ejecútela. Bueno, nos encontramos con un error; y aquí tenemos un serio problema.

En realidad no podemos probar correctamente el mecanismo de captcha, así que tenemos que engañarlo. En modo de prueba validaremos cualquier código como un captcha correcto. Sabemos que estamos en modo de prueba cuando el id del framework es test. Así que vamos a modificar la acción postComment en el archivo yabe/app/controllers/Application.java para saltar está validación cuando estemos en modo de prueba:

…
if(!Play.id.equals("test")) {
    validation.equals(code, Cache.get(randomID)).message("Invalid code. Please type it again");
}
…

Ahora sólo modifique el caso de prueba para que escriba cualquier código en el campo de texto, de esta manera:

…
type('author', 'Me')
type('code', 'XXXXX')
clickAndWait('css=input[type=submit]')
…

Y ahora ejecute la prueba otra vez, debería funcionar.

Midiendo la cobertura de código

Está claro que no hemos escrito todos los casos de prueba que requiere la aplicación. Pero esto es suficiente para este tutorial. Ahora en un proyecto de verdad, ¿cómo podemos saber si hemos escrito suficientes casos de prueba? Necesitamos algo llamado ‘cobertura de código’.

El módulo Cobertura genera reportes de cobertura de código usando la herramienta Cobertura. Instale el módulo utilizando el comando install:

play install cobertura-{version}

Necesitamos habilitar este módulo sólo para el modo de prueba. Así que agregue esta línea al archivo application.conf, y reinicie la aplicación en modo de prueba.

# Import the cobertura module in test mode
%test.module.cobertura=${play.path}/modules/cobertura

Ahora abra nuevamente la URL http://localhost:9000/@tests en el navegador, seleccione todas las pruebas y ejecútelas. Todo debería mostrarse en verde.

Cuando todas las pruebas sean exitosas, detenga la aplicación y Cobertura generará entonces el reporte de cobertura de código. Luego puede abrir el archivo yabe/test-result/code-coverage/index.html en su navegador y revisar el reporte.

Si inicia la aplicación nuevamente, también puede verlo en http://localhost:9000/@cobertura.

Como puede ver estamos lejos de probar todos los casos de la aplicación. Una buena suite de pruebas debería estár cerca del 100%, aunque por supuesto es casi imposible probar todo el código. Normalmente porque con frecuencia necesitamos saltar códigos cuando estamos en modo de prueba, tal como hicimos con el captcha.

Continúa con: Preparando la puesta en producción.