TL;DR

  • Cucumber habilita BDD con tests escritos en inglés simple (sintaxis Gherkin)
  • Feature files describen comportamiento: Given (precondiciones), When (acciones), Then (resultados)
  • Step definitions enlazan pasos Gherkin a código de test real
  • Scenario Outlines habilitan data-driven testing con tablas Examples
  • Se integra con Selenium, TestNG, JUnit para automatización completa

Ideal para: Equipos que quieren tests legibles por negocio, colaboración entre QA y stakeholders Omite si: Equipo pequeño donde desarrolladores escriben todos los tests (testing tradicional más rápido) Tiempo de lectura: 15 minutos

Tus casos de test están en Jira. El código de test está en el repositorio. Los requisitos de negocio están en Confluence. Nadie sabe si los tests realmente cubren los requisitos. Cada sprint, QA explica los mismos escenarios a los stakeholders.

Cucumber cierra esta brecha. Los tests se escriben en inglés simple. Los stakeholders de negocio pueden leerlos. Los desarrolladores los implementan. Todos hablan el mismo lenguaje.

Este tutorial cubre Cucumber desde los básicos de Gherkin hasta integración CI/CD — todo para implementar BDD en tu equipo.

¿Qué es BDD?

Behavior Driven Development (BDD) es un enfoque de desarrollo donde los tests se escriben en lenguaje natural que describe comportamiento de negocio. Los tests se convierten en documentación viva que todos entienden.

Beneficios de BDD:

  • Entendimiento compartido — negocio, QA y dev hablan el mismo idioma
  • Documentación viva — tests describen comportamiento actual del sistema
  • Detección temprana de defectos — requisitos se validan antes de codificar
  • Menos retrabajo — especificaciones claras previenen malentendidos

¿Qué es Cucumber?

Cucumber es una herramienta que soporta BDD ejecutando especificaciones de test en texto plano escritas en Gherkin. Conecta escenarios legibles por humanos con código de test automatizado.

Cómo funciona Cucumber:

  1. Escribes feature files en Gherkin (inglés simple)
  2. Creas step definitions (código que implementa cada paso)
  3. Ejecutas Cucumber — empareja pasos con definitions y ejecuta tests
  4. Obtienes reportes mostrando qué escenarios pasaron/fallaron

Instalación

Java (Maven)

<dependencies>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-java</artifactId>
        <version>7.15.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-testng</artifactId>
        <version>7.15.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.17.0</version>
        <scope>test</scope>
    </dependency>
</dependencies>

JavaScript (npm)

npm install @cucumber/cucumber --save-dev

Estructura del Proyecto

src/test/
├── java/
│   └── com/example/
│       ├── steps/
│       │   └── LoginSteps.java
│       ├── pages/
│       │   └── LoginPage.java
│       └── runners/
│           └── TestRunner.java
└── resources/
    └── features/
        └── login.feature

Sintaxis Gherkin

Feature File

# login.feature
Feature: User Login
  As a registered user
  I want to log into my account
  So that I can access my dashboard

  Background:
    Given the user is on the login page

  Scenario: Successful login with valid credentials
    When the user enters email "user@example.com"
    And the user enters password "password123"
    And the user clicks the login button
    Then the user should see the dashboard
    And the welcome message should contain "Welcome"

  Scenario: Failed login with invalid password
    When the user enters email "user@example.com"
    And the user enters password "wrongpassword"
    And the user clicks the login button
    Then the user should see an error message "Invalid credentials"

Palabras Clave

Palabra ClavePropósitoEjemplo
FeatureDescribe la función a testearFeature: User Login
ScenarioUn caso de testScenario: Successful login
GivenPrecondiciones (setup)Given the user is on the login page
WhenAcciones realizadasWhen the user clicks login
ThenResultados esperadosThen the dashboard is displayed
And/ButPasos adicionalesAnd the user is logged in
BackgroundPasos comunes para todos los escenariosSe ejecuta antes de cada escenario

Step Definitions

Pasos Básicos

// LoginSteps.java
package com.example.steps;

import io.cucumber.java.en.*;
import static org.testng.Assert.*;

public class LoginSteps {

    private LoginPage loginPage;
    private DashboardPage dashboardPage;

    @Given("the user is on the login page")
    public void userIsOnLoginPage() {
        loginPage = new LoginPage(driver);
        loginPage.navigateTo();
    }

    @When("the user enters email {string}")
    public void userEntersEmail(String email) {
        loginPage.enterEmail(email);
    }

    @When("the user enters password {string}")
    public void userEntersPassword(String password) {
        loginPage.enterPassword(password);
    }

    @When("the user clicks the login button")
    public void userClicksLoginButton() {
        dashboardPage = loginPage.clickLogin();
    }

    @Then("the user should see the dashboard")
    public void userShouldSeeDashboard() {
        assertTrue(dashboardPage.isDisplayed());
    }

    @Then("the welcome message should contain {string}")
    public void welcomeMessageShouldContain(String expectedText) {
        String actualMessage = dashboardPage.getWelcomeMessage();
        assertTrue(actualMessage.contains(expectedText));
    }

    @Then("the user should see an error message {string}")
    public void userShouldSeeErrorMessage(String expectedError) {
        String actualError = loginPage.getErrorMessage();
        assertEquals(actualError, expectedError);
    }
}

Scenario Outline (Data-Driven Testing)

Feature: Login Validation

  Scenario Outline: Login with various credentials
    Given the user is on the login page
    When the user enters email "<email>"
    And the user enters password "<password>"
    And the user clicks the login button
    Then the login result should be "<result>"
    And the message should be "<message>"

    Examples:
      | email              | password    | result  | message              |
      | user@example.com   | password123 | success | Welcome back         |
      | admin@example.com  | admin123    | success | Welcome admin        |
      | user@example.com   | wrongpass   | failure | Invalid credentials  |
      |                    | password123 | failure | Email is required    |
      | user@example.com   |             | failure | Password is required |
@Then("the login result should be {string}")
public void loginResultShouldBe(String expectedResult) {
    if (expectedResult.equals("success")) {
        assertTrue(dashboardPage.isDisplayed());
    } else {
        assertTrue(loginPage.hasError());
    }
}

@Then("the message should be {string}")
public void messageShouldBe(String expectedMessage) {
    String actual = getCurrentMessage();
    assertEquals(actual, expectedMessage);
}

Hooks

// Hooks.java
package com.example.steps;

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

public class Hooks {

    private static WebDriver driver;

    @BeforeAll
    public static void beforeAll() {
        // Se ejecuta una vez antes de todos los escenarios
        System.out.println("Iniciando test suite");
    }

    @Before
    public void before(Scenario scenario) {
        // Se ejecuta antes de cada escenario
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        System.out.println("Iniciando: " + scenario.getName());
    }

    @Before("@smoke")
    public void beforeSmoke() {
        // Solo para escenarios con tag @smoke
        System.out.println("Ejecutando smoke test");
    }

    @After
    public void after(Scenario scenario) {
        // Se ejecuta después de cada escenario
        if (scenario.isFailed()) {
            // Screenshot en falla
            byte[] screenshot = ((TakesScreenshot) driver)
                .getScreenshotAs(OutputType.BYTES);
            scenario.attach(screenshot, "image/png", "failure-screenshot");
        }
        driver.quit();
    }

    @AfterAll
    public static void afterAll() {
        // Se ejecuta una vez después de todos los escenarios
        System.out.println("Test suite completado");
    }

    public static WebDriver getDriver() {
        return driver;
    }
}

Tags

@regression
Feature: User Management

  @smoke @critical
  Scenario: Create new user
    Given I am logged in as admin
    When I create a new user
    Then the user should be created

  @slow
  Scenario: Generate user report
    Given I am on the reports page
    When I generate a full user report
    Then the report should be downloaded

Ejecutando Escenarios con Tags

# Solo smoke tests
mvn test -Dcucumber.filter.tags="@smoke"

# Regression pero no slow tests
mvn test -Dcucumber.filter.tags="@regression and not @slow"

# smoke O critical
mvn test -Dcucumber.filter.tags="@smoke or @critical"

Integración con Page Object

// LoginPage.java
public class LoginPage {
    private WebDriver driver;
    private WebDriverWait wait;

    private By emailField = By.id("email");
    private By passwordField = By.id("password");
    private By loginButton = By.id("login-btn");
    private By errorMessage = By.className("error");

    public LoginPage(WebDriver driver) {
        this.driver = driver;
        this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    public void navigateTo() {
        driver.get("https://example.com/login");
    }

    public void enterEmail(String email) {
        wait.until(ExpectedConditions.visibilityOfElementLocated(emailField))
            .sendKeys(email);
    }

    public void enterPassword(String password) {
        driver.findElement(passwordField).sendKeys(password);
    }

    public DashboardPage clickLogin() {
        driver.findElement(loginButton).click();
        return new DashboardPage(driver);
    }

    public String getErrorMessage() {
        return wait.until(ExpectedConditions.visibilityOfElementLocated(errorMessage))
            .getText();
    }
}

Test Runner

TestNG Runner

// TestRunner.java
package com.example.runners;

import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
import org.testng.annotations.DataProvider;

@CucumberOptions(
    features = "src/test/resources/features",
    glue = "com.example.steps",
    plugin = {
        "pretty",
        "html:target/cucumber-reports/report.html",
        "json:target/cucumber-reports/report.json"
    },
    tags = "@smoke or @regression"
)
public class TestRunner extends AbstractTestNGCucumberTests {

    @Override
    @DataProvider(parallel = true)
    public Object[][] scenarios() {
        return super.scenarios();
    }
}

Integración CI/CD

GitHub Actions

name: Cucumber Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: Run Cucumber tests
        run: mvn test -Dcucumber.filter.tags="@smoke"

      - name: Publish report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: cucumber-report
          path: target/cucumber-reports/

Cucumber con Asistencia de IA

Las herramientas de IA pueden ayudar a escribir y mantener tests de Cucumber.

Lo que la IA hace bien:

  • Generar escenarios Gherkin desde user stories
  • Crear step definitions desde feature files
  • Sugerir datos de test para scenario outlines
  • Identificar edge cases faltantes

Lo que aún necesita humanos:

  • Definir escenarios relevantes al negocio
  • Balancear cobertura vs mantenibilidad
  • Validar escenarios con stakeholders
  • Refactorizar pasos duplicados

FAQ

¿Qué es Cucumber?

Cucumber es una herramienta de testing BDD (Behavior Driven Development) que permite escribir tests en inglés simple usando sintaxis Gherkin. Los feature files describen comportamiento de la aplicación que tanto miembros técnicos como no técnicos del equipo pueden entender. Los step definitions conectan estas especificaciones legibles con código de automatización real.

¿Qué es Gherkin?

Gherkin es el lenguaje de dominio específico de Cucumber para escribir escenarios de test en texto plano. Usa palabras clave como Feature, Scenario, Given, When, Then para estructurar tests en formato legible. La sintaxis está diseñada para ser entendida por todos en el equipo — desarrolladores, ingenieros QA, product managers y stakeholders de negocio.

¿Cucumber es gratis?

Sí, Cucumber es completamente gratis y open-source. Está disponible para múltiples lenguajes de programación incluyendo Java, JavaScript, Ruby, Python y Kotlin. No hay versiones pagas ni funciones enterprise — toda la funcionalidad está disponible sin costo.

¿Cucumber vs Selenium — cuál es la diferencia?

Cucumber y Selenium sirven diferentes propósitos y trabajan juntos. Cucumber define qué testear usando escenarios Gherkin (la especificación). Selenium realiza automatización de navegador (la ejecución). En una configuración típica, los escenarios Cucumber describen el comportamiento esperado, y los step definitions usan Selenium para interactuar con el navegador y verificar resultados.

Recursos Oficiales

Ver También