¿Qué es Proptest y para qué sirve?
\n\nProptest es una potente biblioteca para pruebas basadas en propiedades (property-based testing) en el lenguaje Rust. A diferencia de las pruebas unitarias tradicionales, donde se introducen manualmente datos de entrada específicos y resultados esperados, las pruebas basadas en propiedades permiten describir propiedades que su programa debe cumplir para cualquier entrada de datos válida. La biblioteca genera automáticamente múltiples casos de prueba aleatorios y verifica si se cumplen las propiedades definidas.
\n\n¿Para qué sirve?
\n- \n
- Detección de errores ocultos: Los datos aleatorios suelen encontrar casos límite (edge cases) en los que el desarrollador ni siquiera había pensado. \n
- Reducción del volumen de código de prueba: En lugar de escribir decenas de ejemplos, se escribe una sola propiedad. \n
- Minimización automática (shrinking): Si una prueba falla, Proptest intenta automáticamente encontrar el conjunto mínimo de datos de entrada que reproduce el error. \n
- Documentación de la especificación: Las propiedades son afirmaciones formales y verificables sobre el comportamiento del código. \n
Proptest está inspirado en la biblioteca QuickCheck de Haskell, pero adaptado a las particularidades de Rust, incluyendo el manejo de propiedad, préstamo y traits.
Instalación
\n\nProptest es una biblioteca para Rust, por lo que se instala a través del gestor de paquetes Cargo. Agréguela en la sección [dev-dependencies] de su archivo Cargo.toml:
[dev-dependencies]\nproptest = "1.4"\n\nDespués de esto, ejecute el comando cargo build o cargo test para descargar y compilar la biblioteca. Proptest se usa solo durante las pruebas, por lo que no aumenta el tamaño de su binario final.
Para trabajar con código asíncrono (tokio, async-std) puede ser necesaria una configuración adicional, pero en la mayoría de los casos la instalación estándar es suficiente.
\n\nInicio rápido con un ejemplo de código
\n\nEscribamos una prueba simple que verifique que la función reverse (invertir cadena) es una involución: aplicarla dos veces devuelve la cadena original.
// src/lib.rs\npub fn reverse(s: &str) -> String {\n s.chars().rev().collect()\n}\n\n#[cfg(test)]\nmod tests {\n use super::*;\n use proptest::prelude::*;\n\n proptest! {\n #[test]\n fn test_reverse_involution(s in ".*") { // ".*" — cualquier cadena\n let reversed = reverse(&s);\n let double_reversed = reverse(&reversed);\n prop_assert_eq!(s, double_reversed);\n }\n }\n}\n\nEjecute las pruebas: cargo test. Proptest generará 256 cadenas aleatorias (por defecto) y verificará que la propiedad se cumpla. Si la prueba falla, verá un mensaje con el ejemplo mínimo que reproduce el error.
Métodos y funciones principales
\n\nA continuación se presentan los componentes clave de Proptest. Para cada uno se proporciona una descripción, parámetros y un ejemplo.
\n\n1. proptest! — macro para definir pruebas
\nDescripción: Macro principal que ejecuta pruebas basadas en propiedades. Acepta un bloque con funciones de prueba y genera automáticamente los datos de entrada.
\nParámetros: Dentro de la macro, define pruebas con el atributo #[test]. Los datos de entrada se especifican como param in strategy.
Ejemplo:
\nproptest! {\n #[test]\n fn test_addition_commutative(a in 0..100i32, b in 0..100i32) {\n prop_assert_eq!(a + b, b + a);\n }\n}\n\n2. prop_assert! y prop_assert_eq! — aserciones
\nDescripción: Análogos de las aserciones estándar assert!