Scenario Outline y Examples
Scenario Outline y Examples
Scenario Outline es una plantilla parametrizada: el mismo flujo con distintos valores de entrada y salida. Reemplaza N scenarios casi idénticos por una sola plantilla y una tabla de ejemplos.
Sintaxis básica
Scenario Outline: Validación de password durante registro
Given un formulario de registro abierto
When el usuario escribe "<password>" en el campo password
Then el indicador de fuerza muestra "<strength>"
And el botón "Crear cuenta" está "<enabled_or_disabled>"
Examples:
| password | strength | enabled_or_disabled |
| abc | weak | disabled |
| abcdef123 | medium | disabled |
| Abc!def#123$xyz | strong | enabled |
- Los placeholders
<nombre>se reemplazan por valores de la tabla - Cucumber genera un scenario por fila
- En reportes, cada fila aparece como un scenario independiente
Cuándo usar Outline
✅ El mismo flujo con varios inputs:
- Validaciones (varios valores válidos/inválidos)
- Boundaries (mínimo, máximo, justo arriba, justo abajo)
- Permisos (varios roles → varios resultados)
- Configuraciones (varios planes/features → varios resultados)
❌ Cuándo NO usarlo:
- Cuando los scenarios tienen flujo distinto (pasos distintos), no solo valores distintos
- Cuando solo hay 1-2 casos (no vale la complejidad)
- Cuando los pasos del Outline necesitan lógica condicional
Ejemplo: límites de plan
Scenario Outline: Límite de export según subscripción
Given un usuario con subscripción "<plan>"
When solicita un export de "<size_mb>" MB
Then la respuesta tiene status <expected_status>
And el cuerpo contiene "<expected_message>"
Examples:
| plan | size_mb | expected_status | expected_message |
| free | 10 | 200 | Export started |
| free | 50 | 413 | Upgrade to Pro for larger exports |
| pro | 50 | 200 | Export started |
| pro | 200 | 413 | Upgrade to Premium |
| premium | 500 | 200 | Export started |
| premium | 2000 | 413 | Maximum export size exceeded |
Una sola plantilla, seis casos cubiertos, lectura clara.
Múltiples tablas Examples
Podés tener varias tablas, cada una con un nombre opcional, para agrupar casos por categoría:
Scenario Outline: Validación de email
Given el formulario de registro abierto
When escribo "<email>" en el campo email
Then la validación es "<result>"
Examples: Emails válidos
| email | result |
| [email protected] | valid |
| [email protected] | valid |
| [email protected] | valid |
Examples: Emails inválidos
| email | result |
| | invalid |
| not-an-email | invalid |
| @example.com | invalid |
| user@ | invalid |
| [email protected] | invalid |
Los reportes agrupan los scenarios por nombre del Examples.
Outline y tags
Los tags aplican a todos los scenarios generados:
@validation @REQ-AUTH-005
Scenario Outline: Validación de password
...
@critical
Examples: Casos críticos
| password | strength |
| abc | weak |
| a | weak |
@edge-cases
Examples: Bordes
| password | strength |
| exactly-twelve-chars | medium |
| Verylongpassword!@#$%^&*()_+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | strong |
Cómo se ven en step definitions
Las step definitions no cambian: usás los placeholders en el patrón.
TypeScript:
import { Given, When, Then, DataTable } from '@cucumber/cucumber'
When('escribo {string} en el campo email', function (email: string) {
this.formData.email = email
})
Then('la validación es {string}', function (result: string) {
if (result === 'valid') {
assert.equal(this.validator.validate(this.formData.email), true)
} else {
assert.equal(this.validator.validate(this.formData.email), false)
}
})
Python (behave):
from behave import when, then
@when('escribo "{email}" en el campo email')
def step_type_email(context, email):
context.form_data['email'] = email
@then('la validación es "{result}"')
def step_validation(context, result):
is_valid = context.validator.validate(context.form_data['email'])
if result == 'valid':
assert is_valid, f"esperado válido, fue inválido: {context.form_data['email']}"
else:
assert not is_valid, f"esperado inválido, fue válido: {context.form_data['email']}"
Antipatrón 1: Outline con flujos distintos
Scenario Outline: Login
Given un usuario "<type>"
When envía credenciales
- And navega a "<page>" # ⚠ solo aplica si es admin
Then ve "<expected>"
Examples:
| type | page | expected |
| user | | dashboard |
| admin | /admin | panel admin |
Si el flujo cambia según el caso, no es un Outline — son scenarios distintos:
+ Scenario: Login como usuario regular
+ ...
+
+ Scenario: Login como administrador
+ ...
Antipatrón 2: tablas gigantes
Scenario Outline: Crear factura
Given ...
When crear factura con datos
Then ...
Examples:
- | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p |
- | ... |
Si necesitás 15 columnas, partí en varios Outlines más enfocados.
Antipatrón 3: encadenar Outlines
- Scenario Outline: Crear usuario
- ...
-
- Scenario Outline: Editar usuario ⚠ usa los usuarios del Outline anterior
- Given un usuario creado en el scenario anterior
Cada scenario (incluidos los generados por Outline) debe ser independiente. No asumas estado de otros scenarios.
Anti-patrón 4: Lógica condicional en pasos
Scenario Outline: Comportamiento por plan
...
Then la respuesta es "<expected>"
- And si el plan es "free" muestra el upsell ⚠ lógica condicional en step
Mejor partir en dos Outlines o usar Where (en lenguaje EARS, ver tutorial EARS).
Diagrama: expansión de un Outline
flowchart LR
Outline[Scenario Outline] --> R1[Row 1]
Outline --> R2[Row 2]
Outline --> R3[Row 3]
R1 --> S1[Scenario instanciado 1]
R2 --> S2[Scenario instanciado 2]
R3 --> S3[Scenario instanciado 3]
Cada fila → un scenario. Cada scenario ejecuta independiente.
Ejemplo completo: validación de carrito
Feature: Validación de límites del carrito
Background:
Given un cliente registrado
Scenario Outline: Límites de quantity por producto
When el cliente agrega "<sku>" con quantity <qty>
Then la respuesta tiene status <status>
And el cuerpo de error es "<error_message>"
Examples: Quantities válidas
| sku | qty | status | error_message |
| P-100 | 1 | 200 | |
| P-100 | 10 | 200 | |
| P-100 | 100 | 200 | |
Examples: Quantities inválidas
| sku | qty | status | error_message |
| P-100 | 0 | 400 | quantity must be at least 1 |
| P-100 | -1 | 400 | quantity must be at least 1 |
| P-100 | 101 | 400 | quantity cannot exceed 100 |
| P-100 | 9999 | 400 | quantity cannot exceed 100 |
Una sola plantilla cubre el happy path y siete casos de error con bordes explícitos.
Outline + Background + Tags = combo poderoso
@cart @validation
Feature: Validación de carrito
Background:
Given un cliente registrado
@happy-path @REQ-CART-001
Scenario Outline: Agregar productos al carrito
When el cliente agrega "<sku>" con quantity <qty>
Then el carrito contiene la línea (<sku>, <qty>)
Examples:
| sku | qty |
| P-100 | 1 |
| P-101 | 5 |
@error-cases @REQ-CART-002
Scenario Outline: Quantities inválidas son rechazadas
When el cliente agrega "<sku>" con quantity <qty>
Then la respuesta tiene status 400
And el mensaje contiene "<error_message>"
Examples:
| sku | qty | error_message |
| P-100 | 0 | quantity must be at least 1 |
| P-100 | 101 | quantity cannot exceed 100 |
Combinás Background (precondición común), Tags (organización) y Scenario Outline (parametrización). Es la forma canónica de escribir features mantenibles.
Resumen
Scenario Outlineparametriza un scenario con valores deExamples- Una fila → un scenario instanciado
- Soporta múltiples tablas
Examplespara agrupar casos - Útil para validaciones, bordes, configuraciones
- No usar si los scenarios tienen flujos distintos
En el siguiente capítulo cubrimos tags y ejecución selectiva.