Background y reutilización
Background y reutilización
Cuando varios scenarios de una misma feature comparten precondiciones, repetirlas en cada uno viola DRY y dificulta el mantenimiento. Gherkin provee Background para eso.
Sintaxis
Feature: Carrito de compras
Background:
Given un cliente registrado con email "[email protected]"
And la base de datos tiene los productos:
| sku | name | price |
| P-100 | Mouse | 25 |
| P-101 | Keyboard | 80 |
Scenario: Agregar producto al carrito
When ana agrega "P-100" al carrito
Then el carrito de ana contiene 1 línea
Scenario: Quitar producto del carrito
Given ana tiene "P-101" en su carrito con quantity 2
When ana quita "P-101"
Then el carrito de ana está vacío
Los steps del Background corren antes de cada scenario de la feature. No es necesario repetirlos.
Cuándo SÍ usar Background
- Setup de datos comunes: usuarios base, productos, configuraciones que todos los scenarios necesitan.
- Estado inicial inalterable: el sistema arranca limpio en cada scenario.
- Contexto del dominio: información que el lector necesita para entender cualquier scenario del archivo.
Cuándo NO usar Background
Antipatrón 1: Background que no aplica a todos los scenarios
Background:
Given un cliente registrado
- And el cliente tiene una cita agendada para mañana # ⚠ solo aplica a algunos scenarios
Si la cita agendada no aplica a todos los scenarios, sacala del Background. Movela a los scenarios que la necesitan.
Antipatrón 2: Background con acciones (When)
Background:
Given un cliente registrado
- When el cliente inicia sesión # ⚠ When en Background es señal de mal diseño
Background debe contener solo Given. Si el login es precondición para todos los scenarios, expresalo con un Given de más alto nivel:
Background:
Given un cliente autenticado con email "[email protected]"
La step definition del Given encapsula el “iniciar sesión”.
Antipatrón 3: Background gigante
Background:
- Given un cliente registrado
- And la base de datos tiene 200 productos
- And la base de datos tiene 50 cupones activos
- And la base de datos tiene 10 categorías
- And el servicio de pagos está mockeado
- And el feature flag X está habilitado
- And el feature flag Y está deshabilitado
- And el cache está limpio
- And ...
Si tu Background tiene 10+ steps, probablemente:
- La feature está sobrecargada (partila en varias)
- Los Givens son demasiado detallados (subílos un nivel de abstracción)
- Mezclás setup técnico con setup de dominio
Regla: máximo 3-5 steps en el Background.
Background de bajo nivel vs alto nivel
Bajo nivel (mal):
Background:
Given existe un registro en la tabla "users" con id 1 y email "[email protected]"
And existe un registro en la tabla "products" con sku "P-100" y price 25
And existe un registro en la tabla "products" con sku "P-101" y price 80
Alto nivel (bien):
Background:
Given un cliente registrado con email "[email protected]"
And el catálogo tiene los productos:
| sku | name | price |
| P-100 | Mouse | 25 |
| P-101 | Keyboard | 80 |
El Gherkin debe leerse como lenguaje de dominio, no como SQL.
Background y aislamiento de scenarios
Crítico: cada scenario debe poder ejecutarse en aislamiento. El Background ayuda con el setup, pero si los scenarios dependen del orden de ejecución, hay un bug de diseño.
Scenario: Crear el primer usuario
When creo un usuario "[email protected]"
Then existe el usuario "[email protected]"
Scenario: El segundo scenario asume que ana existe
- When ana inicia sesión # ⚠ depende del scenario anterior
+ # Mover la creación al Background o al Given del scenario
Tests independientes pueden correr en paralelo, en cualquier orden, y son más fáciles de debuggear.
Múltiples Backgrounds
Gherkin permite solo un Background por feature. Si necesitás distinto setup para subgrupos de scenarios, partí la feature en varios archivos:
- features/cart.feature con 30 scenarios y 1 Background que no aplica a todos
+ features/cart-empty.feature con scenarios sobre carrito vacío
+ features/cart-with-items.feature con scenarios sobre carrito con items
+ features/cart-checkout.feature con scenarios sobre checkout
Cada uno tiene su Background apropiado.
Background en Python (behave) y TS — implementación idéntica
# features/cart.feature
Feature: Carrito
Background:
Given un cliente registrado
And el catálogo tiene 2 productos
Scenario: Agregar producto
When agrego "P-100"
Then el carrito tiene 1 línea
# features/steps/cart.py
@given('un cliente registrado')
def step_register_client(context):
context.client = Client(email='[email protected]')
@given('el catálogo tiene 2 productos')
def step_seed_products(context):
context.catalog.add(Product('P-100', 25))
context.catalog.add(Product('P-101', 80))
// features/step_definitions/cart.ts
Given('un cliente registrado', function () {
this.client = new Client('[email protected]')
})
Given('el catálogo tiene 2 productos', function () {
this.catalog.add(new Product('P-100', 25))
this.catalog.add(new Product('P-101', 80))
})
(En TypeScript, this referencia al World — lo vemos en el capítulo 10.)
Diagrama: ejecución con Background
sequenceDiagram
participant Cuke as Cucumber
participant BG as Background steps
participant S1 as Scenario 1
participant S2 as Scenario 2
Cuke->>BG: Ejecutar steps del Background
BG-->>Cuke: OK
Cuke->>S1: Ejecutar Scenario 1
S1-->>Cuke: OK
Cuke->>BG: Ejecutar steps del Background (otra vez)
BG-->>Cuke: OK
Cuke->>S2: Ejecutar Scenario 2
S2-->>Cuke: OK
El Background corre antes de cada scenario — no una sola vez al inicio.
Tip: combinar con hooks
Background describe setup de dominio (visible para el lector). Hooks (Before/After) describen setup técnico (limpiar DB, levantar mocks). Combinálos:
// hooks
BeforeAll(async () => {
await dbConnect()
})
Before(async () => {
await truncateAllTables()
await seedMinimalData()
})
AfterAll(async () => {
await dbDisconnect()
})
Background:
Given un cliente registrado con email "[email protected]"
And el catálogo tiene 2 productos
Los hooks limpian el ambiente. El Background define el contexto de dominio.
Resumen
Backgroundevita repetir precondiciones entre scenarios- Máximo 3-5 steps
- Solo Given (nunca When)
- Aplica a todos los scenarios de la feature
- Steps de alto nivel (lenguaje de dominio)
- No reemplaza hooks técnicos
En el siguiente capítulo vemos Scenario Outline y Examples para parametrizar scenarios.