Especificaciones de Concordion en Markdown

0
2261

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.

Especificaciones de Concordion en Markdown

Índice de contenidos

  1. Introducción
  2. Entorno
  3. Creando la especificación con Markdown
  4. Usando tablas para repetir escenarios de prueba
  5. Conclusiones
  6. Referencias

1. Introducción

Como ya nos explicó Daniel Rodríguez, en un
tutorial anterior, Concordion es un framework
pensado para la creación de tests automáticos de aceptación.

En sus primeras versiones, Concordion usaba únicamente HTML como lenguaje para las especificaciones, pero desde la versión 2.0 se ha añadido soporte
para Markdown, un lenguaje de marcado que busca mejorar la legibilidad del documento «en plano», así como facilitar su escritura, basándose en convenciones
existentes previamente para dar «formato» al texto. El uso de estas convenciones es importante porque permite que, usando un intérprete, se pueda transformar este texto
plano en HTML.

2. Entorno

Este tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 17′ (2.8GHz Intel Core i7, 8GB DDR3)
  • Sistema operativo: MacOS Sierra 10.12.3
  • Entorno de desarrollo: IntelliJ IDEA 2017.1, con los plugins «Markdown Support» y «Concordion Support»
  • JDK 1.8
  • Concordion 2.1.0

3. Creando la especificación en Markdown

Vamos a partir de un ejemplo sencillo, un servicio que, dado un nombre, devuelve el saludo correspondiente. Para ello, crearemos en nuestro IDE la especificación.
Esto es especialmente sencillo en IDEA si empleamos el plugin «Concordion Support».

Seleccionamos la carpeta de test, hacemos «click derecho» sobre ella y seleccionamos
la opción «New > Concordion > Spec and fixture». Esto nos creará no sólo la especificación, sino también su «fixture» (clase asociada que implementa la prueba).
Además, podremos seleccionar en qué paquete queremos crear la especificación, con qué lenguaje, etc.

Una vez creada nuestra especificación, insertamos nuestros ejemplos:

    # Pruebas de aceptación del servicio de saludos

    ## Primer ejemplo

    Cuando el usuario indica que su nombre es Marcos, entonces el saludo será Hola, Marcos

    ## Segundo ejemplo

    Cuando el usaurio indique que su nombre es Daniel, entonces el saludo será Hola, Daniel

Como podéis ver, la especificación queda muy limpia, sin el «ruido» de todas las etiquetas HTML, y casi sin necesitad de conocimientos o herramientas adicionales.
El siguiente paso es instrumentalizar la especificación. En nuestro ejemplo, realizaremos dos operaciones: por un lado, tenemos que
asignar valor a una variable; por otro, tenemos que usar esa variable para invocar a nuestro método de prueba y comprobar el resultado. Veamos la sintaxis
necesaria para ambos casos…

    # Pruebas de aceptación del servicio de saludos

    ## Primer ejemplo

    Cuando el usuario indica que su nombre es [Marcos](- "#name"), entonces el saludo será [Hola, Marcos](- "?=greetings(#name)")

    ## Segundo ejemplo

    Cuando el usaurio indique que su nombre es [Daniel](- "#name"), entonces el saludo será [Hola, Daniel](- "?=greetings(#name)")

Lo primero que vemos al revisar la especificación instrumentalizada es la forma en que indicamos a Concordion qué partes de todo lo escrito
tiene que tener en cuenta:

  • Usaremos corchetes ([]) para indicar el texto que tiene que usar para sus operaciones,
    ya sea asignación de variables, comparaciones, etc.
  • A continuación se incluye la operación, con la notación
    (- «operation»).

En el primer caso, (- «#name»), estamos asignando valor a la variable «#name».

En el segundo, (- «?=greetings(#name)»), estamos llamando al método «greetings()» de nuestro fixture,
pasándole como parámetro la variable creada anteriormente, y estamos comprobando que el valor devuelto sea igual al texto entre corchetes (es muy importante
hacerlo como está, sin ningún espacio entre los símbolos «?», «=» y el nombre del método del fixture. En caso contrario obtendremos un error).

También es posible realizar la ejecución del método «greetings» y la aserción en dos pasos. En ese caso, el ejemplo quedaría parecido a esto:

    Cuando el usaurio indique que su nombre es [Marcos](- "#name"), y [solicite un saludo](- "#greeting=greetings(#name)"), entonces el saludo será [Hola, Marcos](- "?=#greeting")

Ahora sólo nos queda implementar el método «greetings()» en nuestro fixture, y podemos ejecutar nuestras pruebas. Puesto que el objetivo de este tutorial es mostrar cómo
hacer especificaciones en Concordion, voy a hacer un fixture muy sencillo, que devuelva directamente el texto que estamos esperando:

    package com.autentia.tutoriales;

    import org.concordion.integration.junit4.ConcordionRunner;
    import org.junit.runner.RunWith;

    @RunWith(ConcordionRunner.class)
    public class Greeting {

        public String greetings(String name) {
            return String.format("Hola, %s", name);
        }
    }

Ahora, si ejecutamos la prueba, obtenemos nuestro resultado (en formato HTML):


4. Usando tablas para repetir escenarios de prueba

Cuando dimos nuestros primeros pasos con Concordion, una de las cosas que vimos fue la posibilidad de usar tablas para ejecutar de manera
iterativa la misma prueba con distintos juegos de datos. Esto también podemos hacerlo con las especificaciones escritas en Markdown. El ejemplo que hemos
usado se presta muy bien a usar una tabla, así que vamos a transformarlo para que así sea. Nuestro escenario queda como sigue

    ## Ejemplo con tablas

    | [greet][][Nombre][name] | [Saludo][greeting] |
    | ---------------| ---------------    |
    | Daniel         | Hola, Daniel       |
    | Marcos         | Hola, Marcos       |

    [name]: - "#name"
    [greet]: - "#greeting=greetings(#name)"
    [greeting]: - "?=#greeting"

Aquí vemos una cosa ligeramente distinta que en los ejemplos que habíamos visto hasta ahora, y es el uso de «etiquetas» para definir fuera de la tabla las acciones
que vamos a realizar sobre cada elemento. Esto no es estrictamente necesario, pero mejora la legibilidad. Pero ¿cómo funciona? Es sencillo… La primera acción
([greet][]) es la acción que se va a repetir para cada registro de la tabla. Después, indicamos que debe ejecutar la acción «[name]» sobre cada elemento de la primera
columna, y «[greeting]» sobre cada elemento de la segunda. Al pie de la tabla aparece definido lo que hace cada «alias»

En este ejemplo hemos hecho una tabla muy sencilla, pero ya podemos intuir que, si la prueba fuera un poco más compleja la tabla no será cómoda de usar ni será fácil saber
qué hace en cada momento (demasiados «alias», posiblemente demasiado separados de su definición si la tabla tiene demasiados registros). Además, es engorroso tener
que «dibujar» la tabla con los separadores de columnas, los de las cabeceras y el cuerpo, etc.

Para evitar todos estos problemas, Markdown nos permite incluir elementos HTML dentro de la especificación (el objetivo final de Markdown es transformarse en HTML,
así que es, por decirlo así, ahorrarnos un paso) encerrándolos en un «div». De esta manera, el siguiente fragmento de especificación sería perfectamente válido,
y tendríamos dos tablas perfectamente válidas funcionando, escritas en disintos lenguajes

      ## Ejemplo con tablas

      | [greet][][Nombre][name] | [Saludo][greeting] |
      | -              | ---------------    |
      | Daniel         | Hola, Daniel       |
      | Marcos         | Hola, Marcos       |

      [name]: - "#name"
      [greet]: - "#greeting=greetings(#name)"
      [greeting]: - "?=#greeting"

      ## Ejemplo con tablas HTML
      <div>
      <table concordion:execute="#greeting=greetings(#name)">
          <thead>
              <tr>
                  <th concordion:set="#name">Nombre</th>
                  <th concordion:assert-equals="#greeting">Saludo</th>
              </tr>
          </thead>
          <tbody>
              <tr>
                  <td>Daniel</td>
                  <td>Hola, Daniel</td>
              </tr>
              <tr>
                  <td>Marcos</td>
                  <td>Hola, Marcos</td>
              </tr>
          </tbody>
      </table>
      </div>

De hecho, si ejecutamos de nuevo nuestra prueba, vemos que el resultado es exactamente igual


5. Conclusiones

Una de los «stoppers» más habituales que podemos encontramos al intentar que personas no técnicas, pero
con un conocimiento profundo del negocio, escriban los escenarios de prueba que se van a automatizar
usando Concordion es el desconocimiento de HTML. Hasta hace poco, las alternativas de que disponíamos eran escasas:
usar una herramienta WYSIWYG para «esconder» el HTML, pero el código generado puede ser muy engorroso para su instrumentalización posterior;
o que nos pasaran los escenarios en un documento de texto (ya sea texto plano o escrito con algun procesador de textos más complejo) y hacer
nosotros la transformación a lenguaje de marcado, lo que supone un doble trabajo.

Ahora, gracias a Markdown, disponemos de una nueva solución para acercar al usuario de negocio a la automatización de pruebas,
pudiéndonos aprovechar de su conocimiento para definir buenos escenarios sin necesidad de trabajar de más

Como ya hemos visto, no es una solución perfecta, pero es una herramienta más a nuestra disposición para conseguir
nuestro fin: asegurar la calidad de nuestro código, tanto desde un punto de vista técnico como funcional. Ahora queda en vuestra
mano saber elegir la mejor opción en cada momento.

6. Referencias

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