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:
- Escribes feature files en Gherkin (inglés simple)
- Creas step definitions (código que implementa cada paso)
- Ejecutas Cucumber — empareja pasos con definitions y ejecuta tests
- 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 Clave | Propósito | Ejemplo |
|---|---|---|
| Feature | Describe la función a testear | Feature: User Login |
| Scenario | Un caso de test | Scenario: Successful login |
| Given | Precondiciones (setup) | Given the user is on the login page |
| When | Acciones realizadas | When the user clicks login |
| Then | Resultados esperados | Then the dashboard is displayed |
| And/But | Pasos adicionales | And the user is logged in |
| Background | Pasos comunes para todos los escenarios | Se 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
- Selenium Tutorial - Fundamentos de automatización de navegador
- TestNG Tutorial - Framework de testing Java
- API Testing Guide - Testing de REST API
- Test Documentation - Escribiendo especificaciones de test efectivas
