Que Es BDD?
Behavior-Driven Development (BDD) es una practica de colaboracion que cierra la brecha entre stakeholders de negocio, desarrolladores y testers. Usa un lenguaje natural estructurado llamado Gherkin para describir el comportamiento esperado del sistema.
La idea central: definir que debe hacer el sistema (comportamiento) antes de implementar como lo hace (codigo).
Sintaxis Gherkin
Gherkin usa tres keywords principales para estructurar escenarios:
- Given — la precondicion (estado inicial)
- When — la accion (lo que hace el usuario)
- Then — el resultado esperado (lo que deberia pasar)
Ejemplo de Feature File
# features/login.feature
Feature: Login de Usuario
Como usuario registrado
Quiero hacer login en mi cuenta
Para poder acceder a mi dashboard
Scenario: Login exitoso con credenciales validas
Given estoy en la pagina de login
When ingreso "admin@test.com" como email
And ingreso "secret123" como password
And hago click en el boton de login
Then deberia ser redirigido al dashboard
And deberia ver "Bienvenido, Admin" como saludo
Scenario: Login fallido con password incorrecto
Given estoy en la pagina de login
When ingreso "admin@test.com" como email
And ingreso "wrongpassword" como password
And hago click en el boton de login
Then deberia ver un mensaje de error "Credenciales invalidas"
And deberia permanecer en la pagina de login
Scenario Outline (BDD Data-Driven)
Scenario Outline: Login con varias credenciales
Given estoy en la pagina de login
When ingreso "<email>" como email
And ingreso "<password>" como password
And hago click en el boton de login
Then deberia ver "<resultado>"
Examples:
| email | password | resultado |
| admin@test.com | secret123 | Bienvenido, Admin |
| editor@test.com | pass456 | Bienvenido, Editor |
| wrong@test.com | wrong | Credenciales invalidas|
| | secret123 | Email es requerido |
Step Definitions
Los step definitions conectan pasos Gherkin con codigo de automatizacion:
const { Given, When, Then } = require('@cucumber/cucumber');
const { expect } = require('@playwright/test');
Given('estoy en la pagina de login', async function () {
await this.page.goto('/login');
});
When('ingreso {string} como email', async function (email) {
await this.page.fill('[data-testid="email"]', email);
});
When('ingreso {string} como password', async function (password) {
await this.page.fill('[data-testid="password"]', password);
});
When('hago click en el boton de login', async function () {
await this.page.click('[data-testid="login-submit"]');
});
Then('deberia ser redirigido al dashboard', async function () {
await expect(this.page).toHaveURL('/dashboard');
});
Then('deberia ver {string} como saludo', async function (greeting) {
await expect(this.page.locator('.welcome-msg')).toHaveText(greeting);
});
Then('deberia ver un mensaje de error {string}', async function (message) {
await expect(this.page.locator('.error-message')).toHaveText(message);
});
Escribiendo Buen Gherkin
Lenguaje de Negocio, No Tecnico
# Mal — demasiado tecnico
Scenario: Test de login
Given navego a "https://app.example.com/login"
When lleno "#email" con "admin@test.com"
And hago click en "#login-btn"
Then la URL deberia ser "/dashboard"
# Bien — comportamiento de negocio
Scenario: Login exitoso
Given soy un usuario admin registrado
When hago login con credenciales validas
Then deberia ver mi dashboard de admin
Declarativo Sobre Imperativo
# Imperativo (muchos pasos, dificil de leer)
Scenario: Comprar un producto
Given abro el navegador
And navego a la pagina principal
And hago click en "Productos"
And busco "Mouse Inalambrico"
And hago click en el primer resultado
And hago click en "Agregar al Carrito"
# Declarativo (comportamiento claro)
Scenario: Comprar un producto
Given estoy logueado como cliente
When agrego "Mouse Inalambrico" a mi carrito
And completo el checkout con mi metodo de pago guardado
Then deberia recibir una confirmacion de orden
Tags para Organizacion
@smoke @login
Feature: Login de Usuario
@positive @critical
Scenario: Login exitoso
Given estoy en la pagina de login
When hago login con credenciales validas
Then deberia ver mi dashboard
@negative
Scenario: Login con cuenta bloqueada
Given tengo una cuenta bloqueada
When intento hacer login
Then deberia ver un mensaje de cuenta bloqueada
Ejecutar con tags:
npx cucumber-js --tags "@smoke"
npx cucumber-js --tags "@smoke and not @negative"
BDD con Playwright-BDD
Playwright-BDD integra la sintaxis Gherkin directamente con Playwright:
import { createBdd } from 'playwright-bdd';
const { Given, When, Then } = createBdd();
Given('estoy en la pagina de login', async ({ page }) => {
await page.goto('/login');
});
When('hago login con {string} y {string}', async ({ page }, email, password) => {
await page.fill('#email', email);
await page.fill('#password', password);
await page.click('#submit');
});
Then('deberia ver el dashboard', async ({ page }) => {
await page.waitForURL('/dashboard');
});
Hooks para Setup y Teardown
const { Before, After } = require('@cucumber/cucumber');
Before(async function (scenario) {
console.log(`Iniciando: ${scenario.pickle.name}`);
this.page = await this.browser.newPage();
});
After(async function (scenario) {
if (scenario.result.status === 'FAILED') {
await this.page.screenshot({
path: `screenshots/${scenario.pickle.name}.png`
});
}
await this.page.close();
});
Anti-Patrones de BDD
1. Escribir Features Despues del Codigo
BDD es una herramienta de colaboracion. Escribir features despues de la implementacion derrota el proposito.
2. Demasiados Escenarios
Un feature con 50 escenarios indica que son demasiado granulares. Apunta a 5-15 escenarios por feature.
3. Cucumber Solo como Herramienta de Test
BDD trata de colaboracion, no solo automatizacion. Si solo QA escribe Gherkin, te pierdes el mayor beneficio.
4. Step Definitions Fragiles
Step definitions acoplados a elementos UI especificos se rompen cuando la UI cambia. Usa page objects dentro de step definitions.
La Reunion de los Tres Amigos
El mayor valor de BDD viene de la reunion “Three Amigos” donde negocio, desarrollo y QA discuten features juntos:
- Negocio explica el comportamiento deseado
- Desarrollo pregunta sobre edge cases y restricciones tecnicas
- QA identifica escenarios que podrian pasarse por alto
El resultado: un conjunto de escenarios Gherkin en los que todos estan de acuerdo antes de escribir una linea de codigo.
Ejercicio: Escribe un Feature BDD
Crea un feature file completo para un carrito de compras e-commerce:
- Escribe una descripcion de feature (Como… Quiero… Para que…)
- Escribe 5 escenarios: agregar item, eliminar item, actualizar cantidad, aplicar codigo de descuento, proceder al checkout
- Usa Scenario Outline con Examples para probar diferentes codigos de descuento
- Agrega tags para smoke, regression y categorizacion positivo/negativo
- Escribe step definitions para al menos 3 escenarios usando page objects
Puntos Clave
- BDD usa Gherkin (Given/When/Then) para describir comportamiento en lenguaje de negocio
- Los feature files sirven como documentacion viva que todos entienden
- Los step definitions conectan Gherkin con codigo de automatizacion
- Escribe escenarios declarativos enfocados en comportamiento, no pasos imperativos
- La reunion Three Amigos es donde se realiza el valor de colaboracion de BDD
- Usa tags para organizar y ejecutar escenarios selectivamente