Proptest Rust: guía completa con ejemplos prácticos

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

Proptest para Rust: guía completa de testing basado en propiedades

1. ¿Qué es y para qué sirve?

La librería proptest es un potente framework de property-based testing (pruebas basadas en propiedades) para el lenguaje Rust. A diferencia de las pruebas unitarias tradicionales, donde tú defines manualmente datos de entrada específicos y un resultado esperado, el testing basado en propiedades te permite describir propiedades (invariantes) que deben cumplirse para cualquier dato de entrada válido. Luego, la librería genera automáticamente múltiples casos de prueba aleatorios y verifica que la propiedad no se rompa.

¿Por qué es útil? Primero, permite encontrar "casos límite" (edge cases) en los que el desarrollador ni siquiera había pensado: cadenas vacías, números negativos, valores muy grandes o estados similares a nulos. Segundo, las pruebas basadas en propiedades son autodocumentadas: describen el contrato de una función ("para cualquier número x, la función f(x) devuelve un número mayor que 0"), no un ejemplo concreto. Tercero, al modificar el código, estas pruebas suelen seguir funcionando sin cambios, ya que verifican propiedades generales, no valores específicos.

proptest es el equivalente en Rust de librerías como QuickCheck (Haskell), Hypothesis (Python) y FsCheck (.NET). Ofrece un rico conjunto de estrategias para generar datos (desde números simples hasta estructuras complejas), un mecanismo de reducción (shrinkage) para minimizar los ejemplos fallidos, e integración con el framework de pruebas principal de Rust: cargo test.

2. Instalación

Para usar proptest, agrégalo en la sección [dev-dependencies] de tu archivo Cargo.toml:

[dev-dependencies]
proptest = "1.4"

Luego, ejecuta el comando:

cargo build

La librería se descargará y compilará. Ahora puedes usarla en tus módulos de prueba.

3. Inicio rápido — ejemplo mínimo funcional

Escribamos una prueba simple que verifique que la función reverse (invertir una cadena) es una involución: si se aplica dos veces, obtenemos la cadena original.

// src/lib.rs
pub fn reverse(s: &str) -> String {
    s.chars().rev().collect()
}

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

    proptest! {
        #[test]
        fn test_reverse_involution(s in ".*") {
            let reversed = reverse(&s);
            let double_reversed = reverse(&reversed);
            assert_eq!(s, double_reversed);
        }
    }
}

Ejecuta la prueba con cargo test. proptest generará 256 cadenas aleatorias (por defecto) y verificará que la propiedad se cumpla. Si la prueba falla, la librería intentará encontrar el ejemplo más pequeño que reproduzca el error.

4. Métodos y funciones principales

A continuación se presentan los componentes clave de la librería proptest. Todos los ejemplos asumen que al inicio del módulo de prueba se ha añadido use proptest::prelude::*;.

4.1. Macro proptest!

Firma: proptest! { ... }

Qué hace: Es la macro principal que define un bloque de pruebas basadas en propiedades. Dentro de ella puedes declarar funciones de prueba con generación automática de datos.

proptest! {
    #[test]
    fn test_addition_commutative(a in 0..100i32, b in 0..100i32) {
        assert_eq!(a + b, b + a);
    }
}

4.2. Estrategia any::<T>()

Recommendations