Pruebas en Rust: unit, integration, e2e — guía completa

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
```html

Introducción: Por qué las pruebas en Rust son simples y confiables

Rust fue diseñado desde el principio como un lenguaje que ayuda a escribir código seguro y confiable. Sin embargo, incluso el sistema de tipos más estricto no garantiza la corrección de la lógica de negocio. Aquí es donde las pruebas vienen al rescate. En Rust, el proceso de escribir pruebas está integrado directamente en la herramienta cargo, lo que lo hace increíblemente conveniente y accesible.

En este artículo, analizaremos tres niveles de pruebas: unit (pruebas unitarias), integration (pruebas de integración) y e2e (end-to-end). Aprenderá cómo escribir pruebas, cuándo usar cada enfoque y cómo automatizar la verificación de su código. El material será útil tanto para principiantes como para desarrolladores experimentados que están migrando a Rust.

Pruebas unitarias: Probando desde adentro

Las pruebas unitarias son el tipo de prueba más básico y común. Verifican funciones, métodos o módulos individuales de forma aislada del resto del sistema. En Rust, es común escribir pruebas unitarias directamente en el mismo archivo que el código bajo prueba, o en un archivo separado tests.rs dentro del módulo.

Cómo escribir pruebas unitarias en Rust

Para crear una prueba se utiliza el atributo #[test]. Las pruebas se colocan en un módulo con el atributo #[cfg(test)], que garantiza que el código de prueba no se incluya en la compilación final.

// src/lib.rs
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

pub fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err(String::from("Division by zero"))
    } else {
        Ok(a / b)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_add() {
        assert_eq!(add(2, 3), 5);
    }

    #[test]
    fn test_add_negative() {
        assert_eq!(add(-1, 1), 0);
    }

    #[test]
    fn test_divide_success() {
        let result = divide(10.0, 2.0);
        assert!(result.is_ok());
        assert_eq!(result.unwrap(), 5.0);
    }

    #[test]
    fn test_divide_by_zero() {
        let result = divide(10.0, 0.0);
        assert!(result.is_err());
        assert_eq!(result.unwrap_err(), "Division by zero");
    }
}

Ejecución de pruebas unitarias

Puede ejecutar las pruebas con un solo comando:

cargo test

La salida mostrará cuántas pruebas pasaron y cuántas fallaron. Para ejecutar una prueba específica, use un filtro:

cargo test test_add

Las pruebas unitarias son ideales para verificar casos límite, manejo de errores y corrección de algoritmos. Son rápidas y no requieren dependencias externas.

Pruebas de integración: Verificando la interacción de módulos

Las pruebas de integración verifican cómo diferentes módulos de su biblioteca o aplicación funcionan juntos. A diferencia de las pruebas unitarias, no tienen acceso a funciones internas (a menos que estén exportadas como pub). Las pruebas de integración se escriben en una carpeta separada tests/ a nivel de la raíz del proyecto.

Estructura de las pruebas de integración

Cree una carpeta tests/ en la raíz de su proyecto y agregue archivos con pruebas. Cada archivo se compilará como un crate independiente.

// tests/integration_test.rs
use my_crate; // nombre de su crate

#[test]
fn test_add_integration() {
    assert_eq!(my_crate::add(10, 20), 30);
}

#[test]
fn test_divide_integration() {
    let result = my_crate::divide(100.0, 4.0);
    assert_eq!(result.unwrap(), 25.0);
}

Módulo común para pruebas

Si varias pruebas de integración utilizan las mismas funciones auxiliares, extráigalas a un módulo común. Para ello, cree la carpeta tests/common/mod.rs:

// tests/common/mod.rs
pub fn setup() {
    // inicialización de logger, base de datos, etc.
    println!("Setting up test environment...");
}

// tests/another_test.rs
mod common;

#[test]
fn test
```                

Blogs

Book Recommendations