Primeros pasos con Concordion

1
5253

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

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:

proyecto-importado-vacio

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:

finalizacion-proyecto

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.

consola-eclipse

Accedemos al informe HTML de Concordion, y comprobamos el resultado final.

informe-concordion

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.

1 COMENTARIO

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad