Utiliser les exemples de documentation
Rust propose d’agrémenter notre documentation d’exemples d’utilisation de nos outils.
C’est une excellente pratique. Elle est grandement facilitée et rendue bien plus utile et sécurisante par l’architecture des outils Rust.
Exemples dans la documentation
L’utilisation native de Markdown permet d’insérer des blocs de codes dans la documentation, notamment pour y placer des exemples d’utilisation.
Dans notre librairie, par exemple :
#![allow(unused)]
fn main() {
/// Calcule le périmètre d'un carré à partir de la longueur de son côté.
///
/// # Exemple
///
/// ```
/// use mon_api_maths::calculer_perimetre;
///
/// let resultat: u64 = calculer_perimetre(5_u32);
/// assert_eq!(resultat, 20_u64);
/// ```
pub fn calculer_perimetre(cote: u32) -> u64 {
(cote as u64) * 4_u64
}
}
Nous avons écrit le code source d’un petit programme exemple pour documenter notre fonction, que nous pouvons extraire et isoler :
#![allow(unused)]
fn main() {
use mon_api_maths::calculer_perimetre;
let resultat: u64 = calculer_perimetre(5_u32);
assert_eq!(resultat, 20_u64);
}
Le programme :
- importe la fonction que nous avons écrite avec
use mon_api_maths::calculer_perimetre;comme le ferait n’importe quel programme qui utiliserait notre API ; - crée une variable
resultatet lui affecte le résultat du calcul, par notre fonction, du périmètre d’un carré de côté5; - utilise une procédure de test pour vérifier que le résultat est bien celui attendu,
5 × 4 = 20, avec la macroassert_eq!(resultat, 20);.
À la différence d’un vrai programme, ce code n’a pas besoin de comporter de fonction
fn main().
Utilisation lors des tests
Rust intègre les exemples de documentation dans la procédure de tests des librairies et des programmes.
Ainsi, si nous effectuons
cargo test
dans notre projet, nous verrons ce retour commande :
$ cargo test
Compiling mon_api_maths v0.1.0 (/home/user/mesprojets/mon_api_maths)
Finished `test` profile [unoptimized + debuginfo] target(s) in 0.20s
Running unittests src/lib.rs (target/debug/deps/mon_api_maths-da3e7a1947867a35)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running unittests src/main.rs (target/debug/deps/mon_api_maths-44a383f15f2f56d8)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests mon_api_maths
running 1 test
test src/lib.rs - calculer_perimetre (line 5) ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
all doctests ran in 0.15s; merged doctests compilation took 0.15s
La partie intéressante est :
running 1 test
test src/lib.rs - calculer_perimetre (line 5) ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
En réalité, Cargo a vérifié la liste des tests unitaires disponibles, a trouvé un code exemple de documentation, et l’a testé dans la partie correspondante.
Pour n’effectuer QUE les tests des exemples de la documentation, nous pouvons nous servir de la commande
cargo test --doc
Avantages
L’avantage principal d’une telle approche est de nous assurer que les exemples que nous produisons dans notre documentation sont valides lorsque nous produisons cette documentation.
Sous réserve, bien sûr,
-
d’avoir respecté tous les éléments du formalisme, c’est à dire d’avoir placé ces blocs dans une syntaxe de ce type :
#![allow(unused)] fn main() { /// ``` /// notre bloc de code — pas besoin de fonction main() — /// ``` } -
de réaliser nos tests unitaires.