BDD en Rust: Escribiendo código vivo con Cucumber y Specs

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Por qué BDD en Rust no se trata de pruebas aburridas

\n\n

Imagine: está escribiendo un servicio de alta carga en Rust. El código es seguro, rápido, pero cuando el producto llega al cliente, él dice: «Pensé que el botón debería funcionar de otra manera». ¿Le suena familiar? La clásica brecha entre el código y las expectativas. Aquí es donde viene al rescate BDD (Behaviour-Driven Development) — una metodología que traduce los requisitos comerciales a un lenguaje comprensible tanto para el gerente como para el compilador de Rust.

\n\n

En este artículo, analizaremos cómo implementar BDD en Rust en la práctica. Aprenderá a escribir escenarios en lenguaje humano (Gherkin), automatizarlos con cucumber y specs, y por qué esto hace que su código no solo sea confiable, sino también transparente para todo el equipo. Sin rodeos: solo código vivo y ejemplos reales.

\n\n

Qué es BDD y por qué Rust es ideal para ello

\n\n

Behaviour-Driven Development es la evolución de TDD. Mientras que TDD se enfoca en «cómo probar el código», BDD responde a la pregunta «qué comportamiento queremos ver». Usted escribe escenarios en lenguaje Gherkin (Given-When-Then), que son tanto pruebas como documentación.

\n\n

Rust es un lenguaje que ama el rigor y la previsibilidad. BDD en Rust ofrece:

\n
    \n
  • Código autodocumentado — cualquier desarrollador lee el escenario y entiende la lógica de negocio.
  • \n
  • Seguridad a nivel de tipos — el compilador verifica que sus pasos coincidan con la estructura.
  • \n
  • Ejecución paralela — las pruebas BDD en Rust funcionan rápido gracias a async y la concurrencia.
  • \n
\n\n

¿Cuándo es especialmente útil BDD en Rust?

\n
    \n
  • Servicios API con contratos claros (REST, GraphQL).
  • \n
  • Sistemas con reglas de negocio (finanzas, logística, juegos).
  • \n
  • Microservicios donde la integración entre componentes es importante.
  • \n
\n\n

Herramientas para BDD en Rust: Cucumber y Specs

\n\n

El ecosistema de Rust ofrece dos enfoques principales:

\n\n

1. cucumber — framework BDD clásico

\n

Permite escribir escenarios en Gherkin (archivos .feature) y vincularlos con código Rust. Soporta async, macros personalizados e informes.

\n\n

2. specs — análogo ligero y rápido

\n

No requiere archivos Gherkin: los escenarios se escriben directamente en Rust usando macros. Ideal si no quiere arrastrar un analizador separado.

\n\n

Nos centraremos en cucumber, ya que ofrece la máxima flexibilidad y cumple con el estándar BDD.

\n\n

Escribiendo nuestro primer escenario BDD en Rust

\n\n

Vamos a crear una calculadora de descuentos simple. Regla de negocio: si el monto de la compra es mayor a 1000 rublos, descuento del 10%. De lo contrario, 0%.

\n\n

Paso 1. Instalación de dependencias

\n

Agregue a Cargo.toml:

\n
[dev-dependencies]\ncucumber = "0.20"\ntokio = { version = "1", features = ["full"] }\nasync-trait = "0.1"\n
\n\n

Paso 2. Crear el archivo feature

\n

Archivo tests/features/discount.feature:

\n
Feature: Cálculo de descuento\n  As un comprador\n  I want obtener un descuento en una compra grande\n  So that ahorrar dinero\n\n  Scenario: Compra mayor a 1000 rublos\n    Given el monto de la compra es "1500"\n    When solicito el cálculo del descuento\n    Then el descuento debe ser "150"\n\n  Scenario: Compra menor a 1000 rublos\n    Given el monto de la compra es "500"\n    When solicito el cálculo del descuento\n    Then el descuento debe ser "0"\n
\n\n

Paso 3. Escribir los pasos en Rust

\n

Cree tests/steps/discount_steps.rs:

\n
use cucumber::{given, then, when, World};\nuse async_trait::async_trait;\n\n#[derive(Debug, Default)]\nstruct DiscountWorld {\n    purchase_amount: f64,\n    discount: f64,\n}\n\n#[async_trait(?Send)]\nimpl World for DiscountWorld {\n    // Implementación vacía para simplificar\n    async fn new() -> Self {\n        Self::d                

Blogs

Book Recommendations