Cucumber es un framework que utiliza el lenguaje Gherkin para especificar las pruebas.
Los ficheros con las features deben estar en el classpath de los test.
Para poder ejecutar escenarios de cucumber de mediante JUnit es necesario configurar una clase Runner, la cual contendrá:
| @Suite @IncludeEngines("cucumber") @SelectClasspathResource("ubicacion") @ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "es.um.atica.[GRUPO].[CONTEXT].cucumber") @TestPropertySource("classpath:test.properties") public class TfCucumberTests { } |
|---|
Las cuales indican:
Su propósito es describir los casos de prueba y agrupar escenarios relacionados. Se escriben en lenguaje Gherkin que sigue una estructura muy cercana al lenguaje natural.
Para describir los escenarios se utilizan algunos conceptos y palabras claves:
Es buena práctica que la descripción en lenguaje natural sea concisa. Debe evitar referencias a la implementación. El comportamiento de implementación lo daremos en los StepDefinition a nivel de clases Java. Un ejemplo de ello seria:
@tf @unauthorized @error Escenario: Obtener info de mi TF sin autenticar Dado un usuario no autenticado Cuando trata de obtener un listado de usuarios Entonces obtiene un error de autenticación |
|---|
Se puede consultar mas información y buenas practicas.
Es un método en java con una expresión que está vinculado con una o varias Steps de Gherkin. Cuando Cucumber procesa un determinado fichero de features busca por la definición correspondiente del step definition y lo ejecuta.
Una vez creados los ficheros feature si ejecutamos los test unitarios el propio framework nos proporciona en la salida una propuesta de los métodos a implementar (Cuidado con los acentos y la "ñ" incluidos en el fichero features).
Siguiendo el ejemplo anterior crearemos la siguiente clase dentro del paquete "es.um.atica.acade.tf.cucumber":
@CucumberContextConfiguration @io.cucumber.java.Before @Dado("un usuario no autenticado") @Entonces("obtiene un error de autenticación") |
|---|
Las anotaciones de la librería @Dado, @Cuando, @Entonces junto con el texto de las mismas son las utilizadas por el framework para hacer el matcheo con la especificación de los ficheros feature.
Dentro de cada método se implementa la lógica correspondiente a la etapa. Para facilitar las cosas podemos crear una clase genérica de "Configuración" que contenga todos los atributos y configuración necesarias para la ejecución de las etapas de cucumber. En nuestro ejemplo "CucumberSpringConfiguration".
Se pueden utilizar expresiones regulares o expresiones de Cucumber para capturar partes de la etapa en Gherkin y pasarlo como parámetros a los step definitions. Veamos un ejemplo:
.features:
| Escenario: Obtener info de mi TF autenticado con TF Dado el usuario autenticado "alumnoTf1@um.es" Cuando trata de obtener mi TF Entonces obtiene una respuesta correcta Y contiene información mi TF Y el titulo del TF es "Mi super TF" |
|---|
.java:
@Y("el titulo del TF es {string}") public void miTfWithTitle(String titulo) throws Exception { EntityModel<miTfDTO> miTF = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<EntityModel<miTfDTO>>() {}); assertEquals(titulo,miTF.getTitulo()); } |
|---|
El método será el seleccionado para ejecutar cualquier step en los ficheros feature que haga match con la expresión indicada. Además se encarga de hacer la conversión de tipos entre el String del fichero feature y el tipo deseado.
Para mapear datos en los ficheros de feature con forma tabular el framework proporciona la clase DataTable. Dispone de una api completa para utilizar de distintas formas de utilizar los datos:
.features:
| @tf @MiTf @detail @success Escenario: Obtener info de mi TF autenticado con TF Dado el usuario autenticado "alumnoTf1@um.es" Cuando trata de obtener mi TF Entonces obtiene una respuesta correcta Y contiene información mi TF Y la informacion del TF es | Mi super TF | Victor Gomollon | 9 | |
|---|
.java
@Y("la informacion del TF es ") public void miTfWithTitle(DataTable dataTable) throws Exception { EntityModel<miTfDTO> miTF = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<EntityModel<miTfDTO>>() {}); assertEquals(dataTable.asLists().get(0),miTF.getTitulo()); assertEquals(dataTable.asLists().get(1),miTF.getAlumno()); assertEquals(dataTable.asLists().get(2),miTF.getCalificacion()); } |
|---|
Son bloques de código que pueden ejecutarse en distintos puntos del ciclo de vida de Cucumber. Un uso típico que se les da es para configurar pasos previos y posteriores a cada escenario. Alguno ejemplos serian:
Permiten organizar features y escenarios de Cucumber. Se pueden utilizar con distintos propósitos:
Se definen en los ficheros feature:
@tf @MiTf @unauthorized @error Escenario: Obtener info de mi TF sin autenticar Dado un usuario no autenticado Cuando trata de obtener mi TF Entonces obtiene un error de autenticación |
|---|
Podemos emplear dicho tag para no ejecutar en un momento dado todos los escenarios que vayan anotados con él, en el starter de JUnit.
@Suite @ConfigurationParameter(key = FILTER_TAGS_PROPERTY_NAME, value = "not @unauthorized") |
|---|
O con mayor prioridad mediante la instrucción en línea de comandos:
| mvn test -Dcucumber.filter.tags="not @unauthorized" |
|---|
Podemos ejecutar:
Con cualquiera de las opciones se va ejecutando un browser para cada escenario. En él se ejecutan las pruebas programadas.
Por defecto los test de cada escenario de prueba se ejecutan de forma secuencial. Con JUnit 5 podemos configurar que se ejecuten los escenarios en paralelo.
Una posibilidad es añadir en el classpath un fichero junit-platform.properties con la siguiente propiedad:
| cucumber.execution.parallel.enabled=true |
|---|
El resto de opciones de configuración se pueden consultar en la documentación.
Cucumber se puede configurar para obtener informes en distintos formatos. Se realiza mediante la propiedad PLUGIN_PROPERTY_NAME:
| @ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "html:target/cucumber.html,json:target/cucumber.json,junit:target/cucumber.xml, com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:") |
|---|
o a través de un fichero de configuración "junit-platform.properties" ubicado en el mismo path que el fichero de properties de tests.
cucumber.publish.quiet=true cucumber.publish.enabled=false cucumber.plugin=pretty, html:target/cucumber-reports/Cucumber.html, json:target/cucumber-reports/Cucumber.json, junit:target/cucumber-reports/Cucumber.xml |
|---|
Genera un informe en html básico en la carpeta y con el nombre indicado. En él podemos ver estadísticas agregadas sobre los test lanzados. Nos proporciona información de cada feature y etapa indicado si se ha ejecutado correctamente o ha fallado.

Misma información pero en formato json o xml. Se puede utilizar como entrada estructurada para otras herramientas de análisis.
Es recomendable utilizar extend reports. Se activa indicando ExtentCucumberAdapter. La salida es en formato html y añade la traza de error vinculada al step. También la captura de pantalla del momento previo al fallo. Esta información facilita trazar los errores en entornos reales con muchos escenarios (Inicialmente NO se usará).

