SE VUOI PRENDERE LA CERTIFICAZIONE PER QUESTO CORSO CLICCA QUI
Corso su Sviluppo della Funzionalità della Libreria con Test-Driven Development
Ora che abbiamo trasferito la logica in src/lib.rs e lasciato la raccolta degli argomenti e la gestione degli errori in src/main.rs, è molto più semplice scrivere test per la funzionalità principale del nostro codice. Possiamo chiamare le funzioni direttamente con vari argomenti e controllare i valori restituiti senza dover chiamare il nostro programma dalla riga di comando.
In questa sezione, aggiungeremo la logica di ricerca al programma minigrep utilizzando il processo di sviluppo guidato dai test (TDD) con i seguenti passaggi:
- Scrivere un test che fallisce ed eseguirlo per assicurarsi che fallisca per il motivo previsto.
- Scrivere o modificare solo abbastanza codice per far passare il nuovo test.
- Rifattorizzare il codice appena aggiunto o modificato e assicurarsi che i test continuino a passare.
- Ripetere dal passaggio 1!
Anche se ci sono molte modalità per scrivere software, il TDD può aiutare a guidare il design del codice. Scrivere il test prima di scrivere il codice che fa passare il test aiuta a mantenere una copertura dei test elevata durante tutto il processo.
Testeremo l’implementazione della funzionalità che effettuerà effettivamente la ricerca della stringa di query nei contenuti del file e produrrà un elenco di righe che corrispondono alla query. Aggiungeremo questa funzionalità in una funzione chiamata search.
Scrittura di un Test Fallimentare
Poiché non ne abbiamo più bisogno, rimuoviamo le istruzioni println! da src/lib.rs e src/main.rs che abbiamo usato per controllare il comportamento del programma. Quindi, in src/lib.rs, aggiungiamo un modulo di test con una funzione di test. La funzione di test specifica il comportamento che vogliamo che abbia la funzione search: prenderà una query e il testo da cercare e restituirà solo le righe del testo che contengono la query.
rust
#[cfg(test)]
mod tests {
use super::*; #[test]
fn one_result() {
let query = "duct";
let contents = "\
Rust:
safe, fast, productive.
Pick three.";
assert_eq!(vec!["safe, fast, productive."], search(query, contents));
}
}
Questo test cerca la stringa “duct”. Il testo che stiamo cercando è composto da tre righe, di cui solo una contiene “duct”. Affermiamo che il valore restituito dalla funzione search contenga solo la riga che ci aspettiamo.
Non siamo ancora in grado di eseguire questo test e vederlo fallire perché il test non compila nemmeno: la funzione search non esiste ancora! In conformità ai principi del TDD, aggiungeremo solo abbastanza codice per far sì che il test compili ed esegua aggiungendo una definizione della funzione search che restituisce sempre un vettore vuoto.
rust
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
vec![]
}
Notiamo che dobbiamo definire un lifetime esplicito ‘a nella firma di search e utilizzarlo con l’argomento contents e il valore di ritorno. Ora eseguiamo il test:
rust
$ cargo test
Compiling minigrep v0.1.0 (file:///projects/minigrep)
Finished test [unoptimized + debuginfo] target(s) in 0.97s
Running unittests src/lib.rs (target/debug/deps/minigrep-9cd200e5fac0fc94) running 1 test
test tests::one_result ... FAILED failures: ---- tests::one_result stdout ----
thread 'tests::one_result' panicked at 'assertion failed: `(left == right)`
left: `["safe, fast, productive."]`,
right: `[]`', src/lib.rs:44:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace failures:
tests::one_result test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
error: test failed, to rerun pass `--lib`
Ottimo, il test fallisce, esattamente come previsto. Ora facciamo passare il test!