Introducción a Cucumber BDD

Cucumber ha revolucionado las pruebas de software al cerrar la brecha entre las partes interesadas técnicas y no técnicas. Como framework de desarrollo orientado al comportamiento (BDD) (como se discute en BDD: From Requirements to Automation), Cucumber permite a los equipos escribir escenarios de prueba en lenguaje sencillo que tanto analistas de negocio como desarrolladores pueden entender, fomentando la colaboración y asegurando que el software cumple con los requisitos reales del negocio.

Esta guía completa explora la automatización con Cucumber (como se discute en Gauge Framework Guide: Language-Independent BDD Alternative to Cucumber) desde los fundamentos hasta técnicas avanzadas, cubriendo sintaxis Gherkin, organización de archivos de características, patrones de definición de pasos, pruebas basadas en datos, hooks y estrategias de reportes comprehensivos.

Entendiendo la Sintaxis Gherkin

Gherkin es el lenguaje específico de dominio legible por humanos de Cucumber para describir el comportamiento del software. Utiliza un formato estructurado con palabras clave específicas para crear especificaciones ejecutables.

Palabras Clave Centrales de Gherkin

Feature: Autenticación de Usuario
  Como usuario registrado
  Quiero iniciar sesión en el sistema
  Para poder acceder a mi cuenta

  Background:
    Given la aplicación está ejecutándose
    And la base de datos está inicializada

  Scenario: Inicio de sesión exitoso con credenciales válidas
    Given estoy en la página de inicio de sesión
    When ingreso el usuario "john.doe@example.com"
    And ingreso la contraseña "SecurePass123"
    And hago clic en el botón de inicio de sesión
    Then debería ser redirigido al panel de control
    And debería ver el mensaje de bienvenida "Bienvenido, John"

  Scenario: Inicio de sesión fallido con contraseña inválida
    Given estoy en la página de inicio de sesión
    When ingreso el usuario "john.doe@example.com"
    And ingreso la contraseña "contraseñaincorrecta"
    And hago clic en el botón de inicio de sesión
    Then debería ver el mensaje de error "Credenciales inválidas"
    And debería permanecer en la página de inicio de sesión

Desglose de Palabras Clave de Gherkin

Palabra ClavePropósitoEjemplo
FeatureAgrupa escenarios relacionadosFeature: Registro de Usuario
BackgroundSe ejecuta antes de cada escenarioBackground: Given usuario logueado
ScenarioCaso de prueba individualScenario: Agregar item al carrito
GivenPrecondiciones/configuraciónGiven estoy en la página principal
WhenAcción/eventoWhen hago clic en "Comprar"
ThenResultado esperadoThen veo confirmación
And/ButConecta pasosAnd recibo email

Organización de Archivos de Características

La estructura efectiva de archivos de características es crucial para la mantenibilidad y claridad.

Mejores Prácticas de Archivos de Características

# features/e-commerce/carrito_compras.feature
@shopping @critical
Feature: Gestión del Carrito de Compras
  Como comprador online
  Quiero gestionar items en mi carrito de compras
  Para poder comprar productos

  Background:
    Given estoy logueado como "usuario_estándar"
    And estoy en la página de productos

  @smoke @cart-add
  Scenario: Agregar un solo producto al carrito
    When agrego "Laptop Computer" al carrito
    Then el contador del carrito debería ser 1
    And el total del carrito debería ser "$999.99"

  @cart-add
  Scenario: Agregar múltiples cantidades del mismo producto
    When agrego 3 unidades de "Cable USB" al carrito
    Then el contador del carrito debería ser 3
    And el total del carrito debería ser "$29.97"

  @cart-remove
  Scenario: Eliminar producto del carrito
    Given tengo "Mouse Inalámbrico" en mi carrito
    When elimino "Mouse Inalámbrico" del carrito
    Then el contador del carrito debería ser 0
    And el carrito debería estar vacío

  @cart-update
  Scenario: Actualizar cantidad de producto en carrito
    Given tengo 2 unidades de "Teclado" en mi carrito
    When actualizo la cantidad de "Teclado" a 5
    Then el contador del carrito debería ser 5
    And el total del carrito debería ser "$249.95"

Scenario Outline para Pruebas Basadas en Datos

# features/authentication/validacion_login.feature
Feature: Validación de Entrada de Login

  @parametrized @validation
  Scenario Outline: Validar login con diferentes credenciales
    Given estoy en la página de inicio de sesión
    When ingreso el usuario "<username>"
    And ingreso la contraseña "<password>"
    And hago clic en el botón de inicio de sesión
    Then debería ver "<result>"

    Examples:
      | username              | password      | result                    |
      | valid@example.com     | ValidPass123  | Bienvenido al Panel       |
      | invalid@example.com   | anything      | Usuario no encontrado     |
      | valid@example.com     | wrongpass     | Credenciales inválidas    |
      | @invalid.com          | ValidPass123  | Formato de email inválido |
      | valid@example.com     | 123           | Contraseña muy corta      |

    @edge-cases
    Examples: Casos Límite
      | username              | password      | result                           |
      |                       | ValidPass123  | Usuario requerido                |
      | valid@example.com     |               | Contraseña requerida             |
      |                       |               | Usuario y contraseña requeridos  |

Definiciones de Pasos: Conectando Gherkin al Código

Las definiciones de pasos traducen los pasos Gherkin a código ejecutable.

Definiciones de Pasos en Java

// src/test/java/steps/AuthenticationSteps.java
package steps;

import io.cucumber.java.en.*;
import pages.LoginPage;
import pages.DashboardPage;
import static org.junit.Assert.*;

public class AuthenticationSteps {
    private LoginPage loginPage;
    private DashboardPage dashboardPage;
    private String actualMessage;

    @Given("estoy en la página de inicio de sesión")
    public void navigateToLoginPage() {
        loginPage = new LoginPage();
        loginPage.navigate();
    }

    @When("ingreso el usuario {string}")
    public void enterUsername(String username) {
        loginPage.enterUsername(username);
    }

    @When("ingreso la contraseña {string}")
    public void enterPassword(String password) {
        loginPage.enterPassword(password);
    }

    @When("hago clic en el botón de inicio de sesión")
    public void clickLoginButton() {
        dashboardPage = loginPage.clickLogin();
    }

    @Then("debería ser redirigido al panel de control")
    public void verifyDashboardRedirect() {
        assertTrue("No está en el panel",
                   dashboardPage.isDisplayed());
    }

    @Then("debería ver el mensaje de bienvenida {string}")
    public void verifyWelcomeMessage(String expectedMessage) {
        String actualMessage = dashboardPage.getWelcomeMessage();
        assertEquals(expectedMessage, actualMessage);
    }

    @Then("debería ver el mensaje de error {string}")
    public void verifyErrorMessage(String expectedError) {
        String actualError = loginPage.getErrorMessage();
        assertEquals(expectedError, actualError);
    }
}

Tablas de Datos: Estructuras de Datos Avanzadas

Las tablas de datos permiten pasar datos complejos a las definiciones de pasos.

Usando Tablas de Datos en Gherkin

Feature: Registro de Usuario

  Scenario: Registrar nuevo usuario con perfil completo
    Given estoy en la página de registro
    When completo el formulario de registro:
      | Campo         | Valor                |
      | Nombre        | Juan                 |
      | Apellido      | Pérez                |
      | Email         | juan.perez@example.com |
      | Teléfono      | +34-555-0123         |
      | Contraseña    | SecurePass123!       |
      | Confirmar     | SecurePass123!       |
    And acepto los términos y condiciones
    And hago clic en el botón de registro
    Then debería ver un mensaje de confirmación
    And debería recibir un email de bienvenida

  Scenario: Crear múltiples productos
    Given estoy logueado como admin
    When creo los siguientes productos:
      | Nombre        | Categoría   | Precio | Stock |
      | Laptop Pro    | Electrónica | 999.99 | 50    |
      | Cable USB-C   | Accesorios  | 9.99   | 200   |
      | Mouse Wireless| Accesorios  | 29.99  | 100   |
    Then todos los productos deberían estar visibles en el catálogo
    And el valor total del inventario debería ser "$53,998.00"

Hooks: Configuración y Limpieza

Los hooks proporcionan gestión del ciclo de vida para escenarios y pasos.

Implementación de Hooks en Java

// src/test/java/hooks/Hooks.java
package hooks;

import io.cucumber.java.*;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import utils.ScreenshotUtils;
import utils.DatabaseUtils;

public class Hooks {
    private WebDriver driver;
    private DatabaseUtils database;

    @BeforeAll
    public static void beforeAll() {
        System.out.println("Iniciando ejecución de suite de pruebas");
        DatabaseUtils.initializeTestDatabase();
    }

    @Before
    public void beforeScenario(Scenario scenario) {
        System.out.println("Iniciando: " + scenario.getName());
        driver = new ChromeDriver();
        driver.manage().window().maximize();
    }

    @Before("@database")
    public void beforeDatabaseScenario() {
        database = new DatabaseUtils();
        database.connect();
    }

    @After
    public void afterScenario(Scenario scenario) {
        if (scenario.isFailed()) {
            byte[] screenshot = ScreenshotUtils.takeScreenshot(driver);
            scenario.attach(screenshot, "image/png", "failure_screenshot");
        }

        if (driver != null) {
            driver.quit();
        }
    }

    @AfterAll
    public static void afterAll() {
        System.out.println("Ejecución de suite de pruebas completada");
        DatabaseUtils.cleanupTestDatabase();
    }
}

Estrategias Avanzadas de Reportes

Los reportes comprehensivos proporcionan información sobre la ejecución y resultados de las pruebas.

Configuración de Reportes de Cucumber

// src/test/java/runners/TestRunner.java
package runners;

import org.junit.runner.RunWith;
import io.cucumber.junit.Cucumber (como se discute en [Serenity BDD Integration: Living Documentation and Advanced Test Reporting](/blog/serenity-bdd-integration));
import io.cucumber.junit.CucumberOptions;

@RunWith(Cucumber.class)
@CucumberOptions(
    features = "src/test/resources/features",
    glue = {"steps", "hooks"},
    tags = "@smoke or @regression",
    plugin = {
        "pretty",
        "html:target/cucumber-reports/cucumber.html",
        "json:target/cucumber-reports/cucumber.json",
        "junit:target/cucumber-reports/cucumber.xml",
        "com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:"
    },
    monochrome = true,
    dryRun = false
)
public class TestRunner {
}

Comparación de Tipos de Reportes

Tipo de ReporteFormatoCaso de UsoCaracterísticas
Reporte HTMLVisualizable en navegadorRevisión humanaInteractivo, capturas
Reporte JSONLegible por máquinaIntegración CI/CDParseable, detallado
JUnit XMLXMLHerramientas Jenkins/CIFormato estándar
Extent ReportHTML enriquecidoDemos a stakeholdersGráficos, filtros, tags
Allure ReportHTML interactivoAnálisis detalladoHistorial, tendencias

Caso de Uso Práctico: Flujo de Compra E-Commerce

@checkout @critical
Feature: Flujo Completo de Compra
  Como cliente
  Quiero completar mi compra
  Para recibir mis productos ordenados

  Background:
    Given existen los siguientes productos:
      | ID Producto | Nombre            | Precio | Stock |
      | PROD001     | Laptop Pro        | 999.99 | 10    |
      | PROD002     | Mouse Inalámbrico | 29.99  | 50    |
    And estoy logueado como "cliente_premium@example.com"

  @smoke @checkout-success
  Scenario: Checkout exitoso con tarjeta de crédito
    Given tengo los siguientes items en mi carrito:
      | ID Producto | Cantidad |
      | PROD001     | 1        |
      | PROD002     | 2        |
    When procedo al checkout
    And selecciono dirección de envío:
      | Calle       | Calle Principal 123 |
      | Ciudad      | Madrid              |
      | Provincia   | Madrid              |
      | CP          | 28001               |
      | País        | España              |
    And selecciono opción de entrega "Envío Estándar"
    And pago con tarjeta de crédito:
      | Número Tarjeta | 4532-1234-5678-9010 |
      | Expiración     | 12/25               |
      | CVV            | 123                 |
      | Nombre         | Juan Pérez          |
    Then el pedido debería estar confirmado
    And debería recibir email de confirmación
    And el total del pedido debería ser "$1,059.97"

Mejores Prácticas para Cucumber BDD

1. Escribir Escenarios Efectivos

# Bien: Declarativo, enfocado en negocio
Scenario: Cliente ve historial de pedidos
  Given soy un cliente logueado
  When navego al historial de pedidos
  Then debería ver mis pedidos pasados

# Mal: Imperativo, enfocado en implementación
Scenario: Cliente ve historial de pedidos
  Given hago clic en el icono de perfil
  When hago clic en el enlace "Historial de Pedidos"
  And espero 2 segundos
  Then debería ver una tabla con clase "order-table"

Conclusión

La automatización BDD con Cucumber transforma las pruebas de software de una actividad puramente técnica a un proceso colaborativo que alinea el desarrollo con los objetivos del negocio. Al usar la sintaxis de lenguaje natural de Gherkin, los equipos pueden crear documentación viva que sirve tanto como especificación y como pruebas automatizadas.

Ventajas clave de Cucumber BDD:

  • Colaboración: Cierra la brecha de comunicación entre miembros técnicos y no técnicos
  • Documentación Viva: Los archivos de características sirven como documentación actualizada del sistema
  • Reusabilidad: Las definiciones de pasos pueden reutilizarse en múltiples escenarios
  • Mantenibilidad: Escenarios legibles por humanos son más fáciles de mantener que pruebas con mucho código
  • Trazabilidad: Mapeo directo entre requisitos y escenarios de prueba

Ya sea que estés probando aplicaciones web, aplicaciones móviles o APIs, Cucumber proporciona la base para pruebas orientadas al comportamiento que mantienen a tu equipo alineado y la calidad de tu software alta.