Introducción
Las pruebas convierten una expectativa en evidencia ejecutable. Una prueba específica ejecuta un comportamiento, compara el resultado real con el esperado y hace que los cambios futuros sean más seguros al detectar regresiones automáticamente.
Añadirá pruebas a una biblioteca preparada para calcular presupuestos de envío. Las funciones de producción son intencionadamente pequeñas para que pueda centrarse en dónde se encuentran las pruebas de Rust, cómo comunican las expectativas las aserciones, qué casos límite son importantes y cómo puede Cargo ejecutar un destino de pruebas cada vez.
Añada una prueba unitaria específica
En este paso, colocará una prueba unitaria junto al código de la biblioteca y ejecutará únicamente esa prueba por su nombre.
El proyecto se encuentra en /home/labex/project/shipping-quote. Acceda a ese directorio:
cd /home/labex/project/shipping-quote
Antes de editar, inspeccione el código fuente breve de la biblioteca. Aquí, el comando sed -n '1,220p' se utiliza únicamente como visor de solo lectura: -n evita la impresión automática y 1,220p indica explícitamente que se impriman las líneas 1 a 220. Ese intervalo es suficiente para mostrar el archivo completo sin abrir un editor:
sed -n '1,220p' src/lib.rs
La sintaxis escrita como #[...] es un atributo: metadatos asociados al elemento de Rust que aparece inmediatamente después. El atributo #[cfg(test)] indica a Rust que compile el módulo de pruebas siguiente únicamente durante las compilaciones de pruebas. Un módulo es un contenedor con nombre para elementos relacionados; en el siguiente Guided Lab aprenderá los módulos como herramienta general de organización.
Dentro de mod tests, la palabra de ruta super representa el módulo principal, y * representa todos los nombres accesibles desde ese módulo. Por lo tanto, use super::*; permite utilizar las funciones de la biblioteca mediante sus nombres abreviados dentro del módulo de pruebas. Por último, una función marcada con #[test] se convierte en una prueba que Cargo puede detectar y ejecutar.
Abra el código fuente con Nano:
nano src/lib.rs
Reemplace // FIRST_UNIT_TEST por esta prueba breve:
#[test]
fn light_parcel_costs_five() {
assert_eq!(shipping_cost(3), 5);
}
assert_eq! compara sus dos expresiones. Si son iguales, la prueba continúa; de lo contrario, la prueba falla e imprime ambos valores. En este caso, la prueba registra que enviar un paquete de tres kilogramos cuesta cinco unidades.
Guarde el archivo con Ctrl+O, pulse Enter y salga con Ctrl+X. Pase el nombre de la prueba después de cargo test para ejecutar únicamente las pruebas cuyos nombres contengan ese texto:
cargo test light_parcel_costs_five
Cargo compila la versión para pruebas e informa sobre la prueba unitaria indicada:
test tests::light_parcel_costs_five ... ok
test result: ok. 1 passed; 0 failed; ...
El prefijo tests:: muestra que la prueba se encuentra dentro del módulo local de pruebas de la biblioteca, y ok confirma que su aserción se aprobó.
Cubra los casos límite
En este paso, añadirá pruebas para los límites donde cambia el comportamiento del envío.
Un valor representativo como 3 demuestra un punto dentro del intervalo de paquetes ligeros, pero los errores suelen ocultarse en los extremos. En el match preparado, 1..=5 es un patrón de intervalo que coincide con cualquier valor del uno al cinco, incluidos ambos extremos. Reutiliza la notación de intervalo inclusivo de los bucles en un nuevo contexto de patrones. La función tiene un comportamiento especial para cero y conserva la tarifa de cinco unidades hasta exactamente cinco kilogramos. Probar esos valores registra ambos límites.
Abra de nuevo la biblioteca:
nano src/lib.rs
Reemplace // EDGE_UNIT_TESTS por estas dos pruebas breves:
#[test]
fn empty_parcel_is_free() {
assert_eq!(shipping_cost(0), 0);
}
#[test]
fn five_kilograms_is_still_light() {
assert_eq!(shipping_cost(5), 5);
}
Cada prueba describe una regla en su nombre y contiene una sola aserción específica. Así, es fácil localizar un error. Guarde el archivo y salga de Nano.
El filtro tests:: coincide con los nombres completos de las pruebas del módulo local de pruebas unitarias. Úselo para ejecutar las tres pruebas unitarias y excluir por ahora el destino independiente de pruebas de integración:
cargo test tests::
La evidencia esperada son tres pruebas unitarias aprobadas:
test tests::empty_parcel_is_free ... ok
test tests::five_kilograms_is_still_light ... ok
test tests::light_parcel_costs_five ... ok
test result: ok. 3 passed; 0 failed; ...
En conjunto, los ejemplos cubren un valor habitual y los dos límites importantes de la regla para paquetes ligeros.
Complete una prueba de integración
En este paso, probará la biblioteca a través de su interfaz pública desde un archivo independiente.
Las pruebas unitarias dentro de src/lib.rs están cerca de la implementación y pueden utilizar los elementos internos del módulo principal. Las pruebas de integración se encuentran en el directorio de nivel superior tests/, se compilan como programas de pruebas independientes y utilizan únicamente la interfaz pública de la biblioteca, como lo haría un código externo. El nombre del paquete shipping-quote se convierte en el nombre de crate de Rust shipping_quote, con un guion bajo, en el código fuente. En el siguiente Lab se consolidará la terminología relacionada con paquetes, crates, módulos y visibilidad pública.
Inspeccione la estructura preparada para la prueba de integración:
sed -n '1,160p' tests/order_workflow.rs
Esta estructura importa únicamente la función pública order_total, la llama para un pedido de 40 unidades y un paquete de tres kilogramos, y deja una aserción para que usted la complete. Abra el archivo:
nano tests/order_workflow.rs
Reemplace la línea de aserción provisional que termina en // INTEGRATION_ASSERTION por:
assert_eq!(total, 45);
El total esperado combina el subtotal de 40 unidades con el coste de envío de cinco unidades correspondiente a un paquete ligero. Guarde el archivo y salga de Nano.
La opción --test order_workflow selecciona el destino de pruebas de integración cuyo archivo es tests/order_workflow.rs:
cargo test --test order_workflow
El destino informa sobre su prueba del flujo de trabajo público:
test order_total_includes_shipping ... ok
test result: ok. 1 passed; 0 failed; ...
Por último, ejecute todo el conjunto de pruebas del paquete sin ningún filtro:
cargo test
Cargo ejecuta las tres pruebas unitarias y la prueba de integración. Es normal que aparezcan resúmenes de resultados independientes porque corresponden a binarios de pruebas diferentes; cada prueba indicada debe mostrar ok y todos los resúmenes deben mostrar cero errores.
Resumen
Añadió pruebas unitarias locales, cubrió los límites de las reglas, completó una prueba de integración mediante la API pública de la biblioteca y utilizó filtros de Cargo para ejecutar una prueba, un módulo, un destino de integración o el conjunto completo. Estos hábitos proporcionan evidencia rápida durante el desarrollo y una protección más amplia contra regresiones antes de entregar el trabajo.


