BDD (Behavior Driven Development). Guía de implementación

Esta guía responde a una intención informacional: entender Behavior-Driven Development (BDD) y ver cómo aplicarlo en Python con ejemplos que se puedan llevar a un repositorio real.
El problema que suelo ver en industria no es “faltan tests”. Es este:
- Negocio pide X.
- El equipo implementa Y.
- En producción aparece el “no era esto”, que se paga con retrabajo, deuda técnica, bugs caros y pérdida de ritmo.
BDD recorta esa distancia usando una idea simple: acordar ejemplos concretos antes de escribir código y, cuando compensa, automatizarlos como tests de aceptación BDD que actúan como documentación viva BDD.
Qué es la metodología BDD (explicado para humanos)
BDD es una metodología dentro de la programación ágil que describe el sistema por su comportamiento observable: lo que hace ante un contexto y una acción.
En vez de discutir sobre “cómo lo vamos a programar”, BDD fuerza otra pregunta:
“Ponme ejemplos. ¿Qué casos concretos deben funcionar?”
Eso aterriza el lenguaje de negocio y reduce ambigüedades.
Los 3 pasos de BDD
Si vienes de TDD, BDD no te resultará extraño. De hecho, una buena forma de entenderlo es verlo como una evolución natural del mismo flujo mental, pero desplazando el foco.
En TDD solemos pensar así:
- Red → escribo un test que falla
- Green → escribo el código mínimo para que pase
- Refactor → limpio y mejoro el diseño
Ese ciclo nos ayuda a diseñar bien el código.
BDD propone un ciclo muy parecido, pero sube un nivel de abstracción. En lugar de empezar por el test técnico, empieza por el comportamiento que el negocio espera.
El paralelismo es bastante directo:
TDD pregunta:
¿Qué función debería existir y cómo debería comportarse internamente?
BDD pregunta primero:
¿Qué debería pasar desde el punto de vista del usuario o del negocio?
A partir de ahí, los 3 pasos de BDD encajan casi como una versión “outside-in” del mismo enfoque:
- Donde TDD empieza escribiendo un test,
BDD empieza descubriendo el comportamiento. - Donde TDD concreta expectativas técnicas,
BDD formula ejemplos de negocio. - Donde TDD automatiza tests unitarios,
BDD automatiza escenarios de aceptación cuando aporta valor.
Si TDD te ayuda a construir bien la solución,
BDD te ayuda a construir la solución correcta.
Con esa idea en mente, vamos paso a paso por los 3 pasos de BDD:
- Discovery: descubrir reglas con negocio, QA y dev (los “3 amigos”).
- Formulation: convertir reglas en escenarios de prueba BDD (Given/When/Then) usando un lenguaje específico del dominio BDD.
- Automation: automatizar escenarios clave (si aporta valor).
El verdadero valor de BDD: menos trabajo tirado
Si has vivido una entrega donde “funciona pero no sirve”, ya sabes el coste:
- semanas perdidas
- reuniones tensas
- hotfixes
- tickets “quick win” que acaban siendo eternos
BDD baja ese riesgo por un motivo: define “hecho” con ejemplos verificables.
Capa estratégica: trade-offs y visión de negocio
Impacto técnico vs impacto de negocio
BDD suele mejorar:
- Velocidad real: menos vueltas de ida y vuelta en validación.
- Coste de cambio: hay menos sorpresas tarde.
- Onboarding: escenarios claros explican el sistema mejor que docs estáticas.
- Riesgo: reglas críticas quedan protegidas con tests.
Y también trae riesgos:
- si el negocio no participa, se vuelve ritual vacío
- si automatizas escenarios frágiles, el CI se convierte en un generador de ruido
- si describís UI en escenarios, se rompe con cada cambio visual
BDD funciona cuando protege valor real. Si no, estorba.
Capa técnica: implementación de BDD en Python con ejemplos
A partir de aquí, vamos a bajar al barro con Python. Voy a usar behave (muy habitual en ecosistema Python) y también te enseño el patrón correcto para que BDD no acabe metiendo lógica en los steps.
Estructura mínima del proyecto
Una estructura típica:
La idea: el comportamiento vive en el dominio y casos de uso. Los steps solo conectan.
1) User story y ejemplos (antes del Gherkin)
Ejemplo (pedido con reembolso):
- Como cliente
- Quiero cancelar un pedido pagado que aún no se ha enviado
- Para recuperar el dinero
Ejemplos que quitan dudas:
- pagado + no enviado → cancelado + reembolso total
- pagado + enviado → no se puede cancelar
- no pagado → se puede cancelar sin reembolso
Con esto ya tienes “casos de uso BDD” reales.
2) Escenario en Gherkin (claro y con datos)
features/cancel_order.feature
Fíjate en lo que NO aparece: rutas, endpoints, botones. Esto describe comportamiento del dominio.
3) Dominio y caso de uso (Python limpio)
app/domain/errors.py
app/domain/order.py
app/use_cases/cancel_order.py
Decisión clave: el caso de uso orquesta. El dominio decide reglas.
4) Doubles en memoria para tests rápidos
features/environment.py
5) Step definitions (sin meter lógica de negocio dentro)
features/steps/cancel_order_steps.py
Este patrón escala bien: los steps llaman a casos de uso, los casos de uso llaman al dominio.
“BDD vs TDD” en Python: cómo los mezclo sin liarla
- BDD: valida comportamiento de negocio (aceptación) con escenarios.
- TDD: valida detalles internos (funciones, invariantes, edge cases) con tests rápidos (pytest).
Una práctica que me ha dado buen resultado:
- 5–15 escenarios BDD para flujos críticos.
- 80–90% del resto en pytest, cerca del dominio.
Errores comunes que he visto en producción
- Escenarios eternos: 20 pasos por escenario. Nadie mantiene eso.
- Escenarios pegados a UI: cambias un texto y rompes “documentación”.
- Automatizar e2e por defecto: tests lentos y frágiles.
- Steps con lógica: reglas repartidas en steps = caos.
Cuándo NO usar BDD
No lo metería si:
- el producto está en fase “todavía no sabemos qué vendemos”
- no hay gente de dominio disponible para acordar ejemplos
- el equipo no puede mantener una suite mínima estable
En esos contextos, prefiero contratos + pytest y volver a BDD cuando el dominio se estabiliza.
Lecciones aprendidas (en primera persona)
He visto BDD convertido en burocracia por intentar automatizarlo todo desde el día 1. Lo típico: features por doc, escenarios por presión, y una semana después el CI falla por ruido. La gente deja de confiar. Y cuando no confías en tus tests, ya has perdido.
Lo que sí me ha funcionado en producción: pocos escenarios, los que protegen dinero, permisos y flujos críticos. Y el resto, tests rápidos cerca del dominio.
FAQ (para fragmentos destacados)
¿Qué es BDD en Python?
Es aplicar BDD (definir comportamiento con ejemplos) en proyectos Python, normalmente escribiendo escenarios Given/When/Then y automatizándolos con herramientas como behave cuando compensa.
¿Behave es obligatorio para hacer BDD?
No. Behave es una herramienta. BDD es el proceso de acordar ejemplos y reglas antes de programar.
¿Qué diferencia hay entre tests de aceptación BDD y tests unitarios?
Los tests de aceptación validan comportamiento de negocio completo. Los unitarios validan piezas pequeñas del código. Ambos se complementan.
¿Cómo evito que BDD se vuelva lento y frágil?
Automatiza pocos escenarios críticos, evita describir UI, y mantén la lógica en dominio/casos de uso, no en los steps.