Tests unitaires

Les tests sont une excellente façon d'assurer la stabilité et le bon fonctionnement de ses applications. Ils servent de documentation sous forme d'exemples, et permettent de bien maintenir toutes les fonctionnalités lorsqu'on fait une modification au code. En D, on peut utiliser la syntaxe très pratique des blocs unittest, qui font partie intégrante du langage. N'importe où dans un module D, des blocs unittest peuvent être insérés pour tester une fonctionnalité.

// Bloc pour ma fonction monAbs
unittest
{
    assert(monAbs(-1) == 1);
    assert(monAbs(1)  == 1); 
}

Cela permet d'appliquer la méthode du Test-driven development de façon très simple.

Exécution des tests unitaires

Les blocs unittest peuvent contenir n'importe quelles instructions, qui sont compilées et exécuté quand le programme est compilé avec l'option -unittest. DUB permet aussi de compiler et d'exécuter les tests grâce à la commande dub test.

Vérifier les exemples avec assert

Habituellement, un bloc unittest contient des assertions (avec assert) qui testent les fonctionnalités d'une fonction donnée. Les blocs unittest sont habituellement placés près de la définition d'une fonction que cette dernière soit au niveau module ou dans une classe ou une struct.

Améliorer la couverture du code

Les tests unitaires sont un bouclier puissant pour blinder ses applications. On appelle la mesure du nombre de lignes de code qui sont testées la couverture du code. C'est le ratio entre le nombre de lignes exécutées par les tests et le nombre de lignes existantes. Le compilateur DMD permet de générer facilement un rapport de la couverture de code en activant l'option -cov. Pour chaque module, un fichier .lst est généré, qui contient des statistiques détaillées sur la couverture.

Comme le compilateur est capable de déduire automatiquement les attributs pour du code schématisé, il est courant d'ajouter des annotations aux tests unitaires, pour être sûr que ces annotations seront appliquées au code testé:

unittest @safe @nogc nothrow pure
{
    assert(monAbs() == 1)
}

Pour aller plus loin

rdmd playground.d