1.11 La primera prueba
Esta traducción fue asistida por IA y revisada superficialmente. Si encuentras errores o algo no suena natural, escríbeme — lo agradezco.
Hacer y verificar no son lo mismo. Un artesano que acaba de terminar una pieza sabe una cosa: parece terminada. Si realmente lo está es otra pregunta, y la respuesta no se ve a simple vista. La tarea puede crearse, completarse y responder una pregunta sobre su estado. La fe es cómoda: no requiere herramientas y funciona al instante. El coste de la comodidad aparece exactamente cuando todo empieza a salir mal.
Lo que necesitas
make ci comprueba la forma: formato sin quejas, clippy sin advertencias. No pregunta por
el comportamiento. El código que parece correcto puede comportarse incorrectamente - la
puerta no lo notará.
Se necesita una forma de hacer preguntas sobre el comportamiento y exigir respuestas en cada ejecución.
La construcción
Los tests viven en un bloque especial al final del archivo:
#[cfg(test)]
mod tests {
use super::*;
}
#[cfg(test)] es un atributo de configuración: este bloque se compila solo al ejecutar
cargo test. No acaba en una compilación normal. use super::* trae los tipos del archivo
padre al ámbito - sin él, Task y Status son desconocidos dentro del bloque.
Un test es una función ordinaria con el atributo #[test]. El nombre describe el
comportamiento que se comprueba, no el método:
#[test]
fn new_task_starts_as_todo() {
let task = Task::new(1, "Buy coffee");
assert!(!task.is_done());
}
assert! comprueba una condición: si es falsa, el test falla. Añade un segundo test:
#[test]
fn complete_marks_task_done() {
let mut task = Task::new(1, "Buy coffee");
task.complete();
assert!(task.is_done());
}
Cuando hay que comparar dos valores, assert_eq! mostrará ambos si falla:
#[test]
fn task_id_is_preserved() {
let task = Task::new(42, "Buy coffee");
assert_eq!(task.id, 42);
}
assert_eq!(left, right) - si left != right, el test falla e imprime ambos valores.
assert! no hace esto: solo sabe “falso.”
El resultado
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_task_starts_as_todo() {
let task = Task::new(1, "Buy coffee");
assert!(!task.is_done());
}
#[test]
fn complete_marks_task_done() {
let mut task = Task::new(1, "Buy coffee");
task.complete();
assert!(task.is_done());
}
#[test]
fn task_id_is_preserved() {
let task = Task::new(42, "Buy coffee");
assert_eq!(task.id, 42);
}
}
running 3 tests
test tests::complete_marks_task_done ... ok
test tests::new_task_starts_as_todo ... ok
test tests::task_id_is_preserved ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
make ci pasa. La puerta ahora pregunta por el comportamiento, no solo por la forma.
El código completo de
tqpara este capítulo está en1-a-task/11-the-first-proof/.
Lore: Lo que no se prueba
Los tests comprueban el comportamiento a través de valores de retorno y estado. list
devuelve () y solo imprime - para verificar su salida habría que capturar stdout. Es
posible, pero las herramientas para ello aparecen más adelante.