Tests de mutation C++ : comment rendre le code invincible

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Tests de mutation en C++ : quand 100% de couverture de code est un mensonge

\n\n

Vous êtes fier de vos 95% de code coverage ? Peut-être à tort. La couverture de code, c'est comme une serrure qu'on vérifie en tirant simplement sur la poignée. Les tests de mutation, c'est le cambrioleur qui essaie réellement d'ouvrir le coffre. Dans cet article, nous allons voir comment les tests de mutation C++ transforment vos tests d'une simple formalité en une véritable arme. Et oui, nous ne copierons pas les définitions ennuyeuses de Wikipédia.

\n\n

Imaginez : vous avez écrit une fonction, vous l'avez couverte de tests, le CI est vert. Et pourtant, un bug part en production. Une douleur familière ? Le plus souvent, le problème ne vient pas du code, mais des tests qui ne vérifient pas ce qu'il faut. Le mutation testing pour C++ résout précisément ce problème : il montre à quel point vos tests sont réellement dangereux pour les bugs.

\n\n

Qu'est-ce que le test de mutation et pourquoi un développeur C++ en a-t-il besoin ?

\n\n

Le test de mutation (ou mutation testing) est une méthode d'évaluation de la qualité des tests en introduisant de petites modifications (mutations) dans le code source. Si les tests réussissent encore après la mutation, c'est qu'ils sont faibles. Le mutant a survécu. Si les tests échouent, le mutant est tué, le test fonctionne.

\n\n

C'est particulièrement pertinent pour le C++, car :

\n
    \n
  • Le code C++ contient souvent une logique complexe avec des pointeurs, des templates et du RAII.
  • \n
  • Les métriques de couverture standard (line coverage, branch coverage) sont faciles à tromper.
  • \n
  • Le coût d'un bug en C++ (notamment dans l'embarqué, la finance, les moteurs de jeu) peut être catastrophique.
  • \n
\n\n

Un exemple simple : vous avez une fonction de vérification d'âge :

\n\n
bool is_adult(int age) {\n    return age >= 18;\n}
\n\n

Test :

\n\n
TEST(AdultTest, Positive) {\n    EXPECT_TRUE(is_adult(20));\n}
\n\n

Couverture : 100% des lignes. Mais la mutation age >= 18 → age > 18 ne sera pas détectée, car 20 passe toujours. Le mutant a survécu. Et si vous aviez un test pour is_adult(18) et is_adult(17) — vous auriez attrapé le bug. Les tests de mutation C++ vous obligent à écrire ces tests aux limites.

\n\n

Opérateurs de mutation principaux en C++

\n\n

Les outils de test de mutation appliquent un ensemble d'opérateurs (mutators). Voici les plus courants pour le C++ :

\n\n
    \n
  • Remplacement des opérateurs arithmétiques : + → -, * → /
  • \n
  • Remplacement des opérateurs logiques : && → ||, == → !=
  • \n
  • Modification des conditions limites : >= → >, < → <=
  • \n
  • Suppression d'expressions : l'appel de fonction est remplacé par une constante
  • \n
  • Modification de la valeur de retour : return true → return false
  • \n
  • Mutation de boucles : modification de la condition de sortie ou du pas
  • \n
\n\n

Exemple avec du code réel :

\n\n
int factorial(int n) {\n    if (n <= 1) return 1;\n    return n * factorial(n - 1);\n}
\n\n

Mutation #1 : n <= 1 → n < 1. Si le test appelle factorial(1) et attend 1, mais que la mutation supprime le cas de base — le test échouera uniquement si vous vérifiez factorial(0) ou factorial(1) séparément.

\n\n

Mutation #2 : return n * factorial(n - 1) → return n + factorial(n - 1). Si les tests ne portent que sur des nombres positifs, ils pourraient ne pas remarquer la substitution de la multiplication par l'addition.

\n\n

Ce sont précisément ces cas que le mutation testing en C++ révèle.

\n\n

Outils pour les tests de mutation en C++

\n\n

Tous les outils ne se valent pas. Voici les trois principaux acteurs sur le marché du C++ :

\n\n

1. Mull

\n

Un projet moderne et actif. Fonctionne sur la base d'un pass LLVM. Prend en charge C++17/20, s'intègre avec Google Test, Catch2, doctest

Blogs

Book Recommendations