En este tutorial nos iniciaremos en el mundo de los tests de aceptación de la mano del framework Concordion.
Índice de contenidos
- 1. Introducción
- 2. Entorno
- 3. Preparación del entorno
- 4. Creación de los tests HTML
- 5. Creación del fixture en Java
- 6. Creación del servicio
- 7. Puesta en ejecución de los tests de aceptación
- 8. Conclusiones
- 9. Saber más
1. Introducción
Concordion es un framework orientado al desarrollo de tests de aceptación. Funciona a través de tests escritos en HTML o a través de lenguaje de marcado (a partir de la versión 2.0) que a su vez son instrumentalizados con atributos especiales que el framework interpreta para ejecutar dichos tests.
En vez de forzar a que los Product Owners tengan que especificar los requisitos en un lenguaje con una determinada estructura, Concordion permite definirlos utilizando lenguaje natural, pudiendo utilizar párrafos, tablas, y signos de puntuación. Esto hace que las especificaciones sean mucho más legibles y sencillas de escribir, además de ayudar enormemente a la compresión y aceptación de lo que se supone debe de hacer la funcionalidad que vamos a probar.
2. Entorno
El tutorial se ha realizado en el siguiente entorno:
- MacBook Pro 15″ – 2 GHz Intel Core i7 – 8 GB 1333 MHz DDR3
- OS X El Capitan v10.11.4
- Maven 3
- Java JDK 1.8
- Eclipse IDE Mars (4.5.0)
3. Preparación del proyecto
Para la realización del tutorial, prepararemos un proyecto básico utilizando el arquetipo «maven-archetype-quickstart» de Maven.
Para ello, accedemos a través de nuestra consola al directorio donde queramos generar nuestro proyecto (típicamente nuestro workspace local), y ejecutamos el siguiente comando.
mvn archetype:generate -DgroupId=com.examples.concordion -DartifactId=helloworld-concordion -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
Una vez Maven haya generado el proyecto, abrimos el Eclipse IDE, seleccionamos el workspace correspondiente e importamos el proyecto Maven en nuestro workspace local.
Después de importarlo, añadimos la carpeta «src/test/resources» al proyecto, y a continuación la incluimos en el buildpath del mismo, a través del menú de propiedades del proyecto en Eclipse IDE. Posteriormente, eliminamos los ficheros autogenerados por el arquetipo y quitamos también la dependencia de Junit en el POM.
Por último, modificamos el fichero pom.xml para incluir la dependencia de Concordion.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.examples.concordion</groupId> <artifactId>helloworld-concordion</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>helloworld-concordion</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>org.concordion</groupId> <artifactId>concordion</artifactId> <version>2.0.0</version> <scope>test</scope> </dependency> </dependencies> </project>
Finalizada la preparación, el proyecto deberá de tener este aspecto:
4. Creación de los tests HTML
Después de haber preparado el proyecto, es hora de meterse en harina empezando por la redacción de los tests de aceptación que queremos disponer en nuestro proyecto. En el caso de este tutorial, se va a utilizar el formato HTML para la creación de los mismos (a partir de la versión v2.0 de Concordion, es posible utilizar lenguaje de marcado).
En este tutorial realizaremos dos tests:
- Ejemplo básico en donde el test es un pequeño párrafo de HTML
- Ejemplo con uso de tablas, donde cada fila de la tabla servirá como dato de entrada para generar una salida determinada.
4.1. Creación y preparación de la estructura básica HTML
Para preparar nuestros tests HTML, primero debemos crear nuestro fichero en la ruta ‘src/test/resources’, colgando del paquete correspondiente en donde posteriormente ubicaremos nuestro fixture de instrumentalización (escrito en Java).
Creamos el fichero HTML ‘src/test/resources/com/examples/concordion/HelloWorld.html’. A continuación le damos la estructura básica de HTML, incluyendo el namespace de Concordion, para poder utilizar la funcionalidad del framework en la creación de nuestros tests de aceptación.
<html xmlns:concordion="http://www.concordion.org/2007/concordion"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <h1>Primeros pasos con Concordion</h1> <h3>Ejemplo básico</h3> <!-- Aquí irá el ejemplo básico --> <h3>Ejemplo con tabla</h3> <!-- Aquí irá el ejemplo con tabla--> </body> </html>
Una vez dispuesta la estructura básica, pasamos a dotarla de contenido a través de los ejemplos que hemos enumerado anteriormente.
4.2 Contenido del ejemplo básico
En este ejemplo básico, se dispondrá el test para comprobar que el saludo de un hipotético usuario es el correcto.
<p> Dado una persona llamada <b concordion:set="#userName">Frodo Bolsón</b><br/> el saludo deberá ser <span concordion:assertEquals="greetings(#userName)">Hola Frodo Bolsón!</span> </p>
Observad que utilizando el atributo ‘concordion:set=»#userName»‘, vamos a almacenar el contenido del tag ‘b’, en este caso ‘Frodo Bolsón’, en la variable ‘#userName’ de Concordion. Posteriormente, se utiliza el atributo ‘concordion:assertEquals=»greetings(#userName)»‘, para invocar al método «greetings» de nuestro fixture asociado escrito en código Java (explicado en pasos posteriores).
4.3 Contenido del ejemplo con tabla
En este otro ejemplo, nos apoyaremos en el uso de una tabla para poder ser más ágiles a la hora de realizar tests de aceptación que cuya funcionalidad deba ser la misma, pero aplicada esta vez a una lista de elementos; en nuestro caso de nombres de usuario.
<p> <table concordion:execute="#greeting = greetings(#userNameInTable)"> <tr> <th concordion:set="#userNameInTable">Nombre Usuario</th> <th concordion:assertEquals="#greeting">Saludo del sistema</th> </tr> <tr> <td>Arkady Darell</td> <td>Hola Arkady Darell!</td> </tr> <tr> <td>Raistlin Majere</td> <td>Hola Raistlin Majere!</td> </tr> <tr> <td>Myca Vykos</td> <td>Adiós Myca Vykos!</td> </tr> </table> </p>
Utilizando la tabla HTML, declaramos en el tag ‘table’ el atributo ‘concordion:execute=»greeting = greetings(#userNameInTable)»‘, el cual lo que hará será ejecutar por cada una de las filas de la tabla la funcion ‘greetings(..)’, almacenando el resultado en la variable ‘#greeting’.
Posteriormente, a través de la definición de las cabeceras de la tabla, estamos indicando a Concordion qué fila concreta corresponde a qué dato, y qué función de Concordión se debe ejecutar en cada una de ellas.
Como se puede observar, en la primera fila vamos a definir el nombre del usuario a través del atributo ‘concordion:set=»#userNameInTable»‘, y en la segunda fila vamos a evaluar el saludo del sistema esperado a través del atributo ‘concordion:assertEquals=»#greeting»‘.
5. Creación del fixture en Java
Una vez hemos escrito los tests de aceptación que queremos realizar en nuestro tutorial, vamos a realizar el fixture de Concordion que instrumentalizará el contenido de dichos tests de aceptación.
Para ello, creamos el fichero ‘src/test/java/com/examples/concordion/HelloWorld.java’. Daos cuenta de que la paquetería y el nombre del fichero son exactamente los mismos que la paquetería y el nombre del fichero HTML, con la diferencia de que uno cuelga de ‘src/test/java’ y el otro cuelta de ‘src/test/resources’. Este punto es importante, ya que si no seguimos estas directrices, Concordion no va a saber encontrar el fichero de instrumentalización.
En nuestro fixture, incluimos el runner de Concordion, para indicar que dicho test lo ha de ejecutar el framework, y posteriormente incluímos la función «greetings» que habíamos utilizado en nuestros tests HTML.
Como es una buena práctica separar la lógica que subyace al test del propio test, el encargado de generar el saludo del usuario será un pequeño servicio que veremos posteriormente. Esta práctica es capital para mantener unos tests robustos, que no estén acoplados a la implementación.
@RunWith(ConcordionRunner.class) public class HelloWorld { private final GreetingService greetingService = new GreetingService(); public String greetings(final String userName) { return greetingService.greetings(userName); } }
6. Creación del servicio
Finalmente, vamos a crear el servicio que generará el saludo del usuario. Este servicio, al no ser una clase de test, debemos incluirlo dentro del buildpath ‘src/main/java’, como viene siendo habitual en los proyectos Maven. Creamos la clase ‘src/main/java/com/examples/concordion/GreetingService.java’
En este servicio, creamos un método ‘greetings(…)’, el cual utilizará nuestra clase de test (nuestro fixture) para poder generar el saludo.
public class GreetingService { public String greetings(final String username){ final StringBuilder sb = new StringBuilder(); return sb.append("Hola ").append(username).append("!").toString(); } }
7. Puesta en ejecución de los tests de aceptación
Finalizado la codificación de nuestros tests de aceptación junto con sus fixtures, el proyecto debería de tener una pinta parecida a esta:
Por último, ya solo resta ejecutar el fixture ‘HelloWorld.java’, utilizando la configuración de JUnit. Tras la ejecución, se presentará en la consola del Eclipse IDE el resumen de los tests ejecutados y la ruta donde se ha generado el informe de Concordion.
Para este ejemplo, se ha dejado un test en estado fallido para visualizar el aspecto de dichos tests.
Accedemos al informe HTML de Concordion, y comprobamos el resultado final.
8. Conclusiones
En este tutorial hemos visto como dar nuestros primeros pasos en el uso de Concordion como framework de tests de aceptación utilizando un ejemplo básico y un ejemplo basado en tablas, utilizando HTML como lenguaje de escritura de los tests.
Puedes echar un vistazo del código fuente completo a través de este enlace a mi repositorio de GitHub: Primeros pasos con Concordion – GitHub
9. Saber Más
Si quieres profundizar en los conceptos de Tests de aceptación o en los atributos de Concordion disponibles, te dejo estos enlaces.
- TDD, BDD & Test de aceptación
- Concordion – Home Page
- Lista de Comandos de Concordion
[…] Después de dar los primeros pasos con Concordion de la mano de nuestro compañero Daniel Rodríguez, vamos a profundizar en una de las novedades de la versión 2 de este framework de pruebas automáticas: el uso de Markdown para escribir nuestras especificaciones. […]