Testing
🧩 BDD (Behavior-Driven Development)
📘 Conceptos
- Behavior-Driven Development
- Extensión de TDD - Test Driven Development centrada en el comportamiento del sistema.
- Permite comunicación clara entre desarrolladores, QA y negocio.
- Lenguaje Específico de Dominio (DSL)
- Lenguaje legible por humanos para definir comportamientos.
- Ejemplo: Gherkin.
- Gherkin
- Sintaxis estándar para definir escenarios BDD.
- Palabras clave:
Feature,Scenario,Given,When,Then,And,But. - Estructura básica: given, when, them - practica bdd
- Ejemplo práctico:
- logica de negocio
- Los tests se escriben desde la perspectiva del comportamiento esperado.
- Permite validar funcionalidades de extremo a extremo y alinearlas con los objetivos del negocio.
- Los escenarios describen qué se espera del sistema, no cómo se implementa.
- El código se escribe después, validando ese comportamiento.
Feature: Login de usuario
Scenario: Usuario inicia sesión correctamente
Given el usuario existe con email "user@test.com" y password "1234"
When el usuario envía una solicitud POST a "/login"
Then el sistema responde con código 200 y un token JWT
🧾 Documentación y referencias
- ¿Qué es BDD (Behavior Driven Development)-
- BDD Testing. ¿Cómo funciona el Behavior Driven Development-
🛠️ Tools BDD
- Behat
- Behat Documentation — Behat documentation-guides.html
- Compatible con Gherkin.
- SpecFlow
- Integración con .NET y Visual Studio.
- Permite definir escenarios en Gherkin.
- Behave
- Framework BDD para Python.
- Compatible con Selenium y pruebas automatizadas.
- cucumber
- Framework multiplataforma (JS, Java, Ruby, etc.).
- Ejecuta escenarios definidos en Gherkin enlazados a código con step definitions.
🔄 Buenas prácticas BDD
- Escribir los escenarios antes de implementar la funcionalidad.
- Involucrar Testing, QA y desarrollo en la definición de escenarios.
- Mantener el DSL consistente y legible para toda la organización.
- Priorizar features críticas y flujos de negocio.
- Reutilizar pasos comunes con step definitions.
- Integrar BDD en pipelines de CI/CD para asegurar validación continua de comportamiento.
🧠 Flujo general BDD
- Definir el comportamiento esperado en lenguaje Gherkin.
- Implementar los step definitions que conectan los pasos con código real.
- Ejecutar los tests con una herramienta BDD (Cucumber, Behat, etc.).
- Integrar los resultados en el pipeline CICD para validar continuamente.
Buenas prácticas BDD
- Iniciar cada feature con una historia de usuario clara.
- Escribir escenarios legibles y sin lógica técnica.
- Evitar repetir pasos; usar steps reutilizables.
- Mantener una nomenclatura coherente (nombres naturales y consistentes).
- Automatizar la ejecución en pipelines CI/CD.
- Integrar herramientas de reporting (Allure, Cucumber Reports, etc.).
- Usar mocks o stubs para componentes externos cuando sea necesario.
- Documentar escenarios fallidos con capturas o logs de ejecución.
💻 Ejemplos Prácticos de BDD
🥒 Ejemplo Cucumber (JavaScript)
Feature: Autenticación
Scenario: Login exitoso
Given el usuario "admin" con contraseña "1234"
When intenta iniciar sesión
Then el sistema muestra "Bienvenido, admin"
import { Given, When, Then } from "@cucumber/cucumber";
import assert from "assert";
let user;
Given('el usuario {string} con contraseña {string}', function (username, password) {
user = { username, password };
});
When('intenta iniciar sesión', function () {
this.result = user.password === "1234" ? "Bienvenido, admin" : "Error";
});
Then('el sistema muestra {string}', function (message) {
assert.strictEqual(this.result, message);
});
🐍 Ejemplo Behave (Python)
Feature: Registro de usuario
Scenario: Crear nuevo usuario
Given un formulario válido
When el usuario envía sus datos
Then el sistema responde con "Usuario creado correctamente"
# steps/registro_steps.py
from behave import given, when, then
@given('un formulario válido')
def step_given_form(context):
context.formulario = {"nombre": "Carlos", "email": "test@test.com"}
@when('el usuario envía sus datos')
def step_when_submit(context):
context.resultado = "Usuario creado correctamente"
@then('el sistema responde con "{mensaje}"')
def step_then_response(context, mensaje):
assert context.resultado == mensaje
🧩 Ejemplo SpecFlow (.NET / C#)
Feature: Calculadora
Scenario: Sumar dos números
Given el primer número es 5
And el segundo número es 7
When los sumo
Then el resultado debe ser 12
using TechTalk.SpecFlow;
using NUnit.Framework;
[Binding]
public class CalculadoraSteps
{
private int num1, num2, resultado;
[Given(@"el primer número es (.*)")]
public void DadoElPrimerNumeroEs(int n) => num1 = n;
[Given(@"el segundo número es (.*)")]
public void DadoElSegundoNumeroEs(int n) => num2 = n;
[When(@"los sumo")]
public void CuandoLosSumo() => resultado = num1 + num2;
[Then(@"el resultado debe ser (.*)")]
public void EntoncesElResultadoDebeSer(int esperado)
=> Assert.AreEqual(esperado, resultado);
}
🧱 Ejemplo Behat (PHP)
Feature: API de usuarios
Scenario: Consultar datos del usuario
Given existe un usuario con ID 1
When hago una petición GET a "/users/1"
Then la respuesta contiene "nombre"
<?php
use Behat\Behat\Context\Context;
use PHPUnit\Framework\Assert;
class UserContext implements Context
{
private $response;
/** @Given existe un usuario con ID :id */
public function existeUsuario($id)
{
// Simulación de existencia de usuario
}
/** @When hago una petición GET a :endpoint */
public function hagoPeticionGET($endpoint)
{
$this->response = ["nombre" => "Carlos"];
}
/** @Then la respuesta contiene :campo */
public function respuestaContiene($campo)
{
Assert::assertArrayHasKey($campo, $this->response);
}
}
¿Te gusta este contenido? Suscríbete vía RSS