7
votes

Test de l'unité pour les erreurs de compilateur

Comment testez-vous les erreurs de compilateur levée recherchées dans les tests d'unités?

Considérez le code: P>

ErrorTest test;
OtherClass other = test.read_only();
test.read_write() = other.modify();
test.read_only() = other.modify(); /* This should error */


1 commentaires

Bonne question. Je me suis demandé la même chose auparavant. Jamais vraiment trouvé de bonnes réponses cependant. Bien sûr, vous pouvez écrire un script qui tente de compiler le fichier et vérifie le code d'erreur ou quelque chose, mais c'est à peine une solution élégante.


4 Réponses :


1
votes

Je suppose que la question principale est maintenant, testez-vous que votre code ou le compilateur à ce stade?

Tester le compilateur n'est pas nécessairement une mauvaise chose ... J'ai eu des erreurs de masque du compilateur dans le passé, il serait donc agréable de vous assurer que vous obtenez le même ensemble de contrôles de sécurité que vous attendez. < / p>

Cependant, vous devrez faire beaucoup de poids. Votre test de l'unité devra apparaître le compilateur, capturera sa sortie et l'analyser pour l'instruction d'erreur correcte sur la bonne ligne. Ce n'est pas trivial et sans doute pas la peine.

Une approche légèrement plus facile pourrait être de conserver un répertoire du code néflutique et d'avoir un script compiler chaque fichier à la fois. Avoir un drapeau '#Ifdef makefail' de là qui allume la condition exacte qui devrait échouer. Assurez-vous que le compilateur renvoie 0 lorsque vous ne définissez pas cet indicateur et non à zéro lorsque vous faites. Cela suppose que le compilateur renvoie non-zéro en échec ... Je ne sais pas si MSVC suit cette règle.

Une troisième option je vais jeter là-bas, pour répondre à la portabilité, est Autoconf. Cela peut être une douleur à mettre en place, mais une partie de son objectif était de veiller à ce que vous ayez un environnement de développement en sens unique avant de compiler. Vous pouvez ajouter un test comme celui-ci et laissez la manipulation de la recherche du compilateur et de l'essayer.


7 commentaires

Il teste que son code est Const-correct. Je pense donc qu'il teste toujours son code, il s'agit simplement de tester les propriétés qui ne sont évidentes que pour la compilation.


Je lis cela comme il essaie de veiller à ce que le compilateur génère les avertissements, pas qu'il n'y ait aucun avertissement. Il semble qu'un peu redondant d'avoir un test d'unité vous indique que votre compilation s'est plainte, mais peut-être que si vous avez un bel appareil-test-analyse-analyse, cela a du sens.


Il essaie de s'assurer que le compilateur produit une erreur, pas un avertissement. Il y a beaucoup de cas dans C ++ où cela a du sens. Const L'exactitude est un exemple, mais si vous jouez avec des modèles, cela survient souvent.


Peut probablement le simplifier en vérifiant simplement le code de retour sur compilateur, sans analyse de panne. Mais il faut avoir un fichier de contrôle correspondant pour chaque test, qui compilerait réellement (tout la même ligne, mais une ligne incriminée appelée correctement ou commentée). Donc, le test passe lorsque un fichier compile et on échoue pour chaque cas.


(Ou même utilise un fichier par test mais #Ifdef délinquant code pour la deuxième compilation)


@Chris: Il essaie d'attraper l'erreur de programmeur d'oublier de marquer la valeur de retour de Read_only comme const. Donc, si le code lu « AutreClasse & read_only () » au lieu de « const AutreClasse & read_only () const », le code de test compilerait au lieu de donner une erreur, et il veut que pour être un échec du test. Je pense.


J'aime vraiment la deuxième approche, mais je me demande une portabilité, en particulier lorsque vous travaillez à l'aide de plusieurs compilateurs (GCC, ICC et MSVC) à travers les systèmes d'exploitation. Un script Bash va-t-il faire?



1
votes

Cela semble un peu comme la détection automatique qui se produit lorsque vous "./configure" pour une version à partir de la source sur une machine * Nix. Les scripts Autoconf construisent de petits programmes et tentent de les compiler pour déterminer ce qui est disponible et pris en charge par votre compilateur.

Ce n'est probablement pas pratique de réutiliser quelque chose, mais vous voudrez peut-être le même modèle. Chaque test aurait son propre fichier ou défini de fichiers, et un fichier de projet séparé / crée cible / etc .. Ensuite, votre script de test tenterait de faire chaque cas de test et de vérifier que l'erreur attendue s'est produite, via Grep ou en comparant le sortie à une sortie de base stockée avec les cas de test.


0 commentaires

0
votes

Un test valide du compilateur et de la plate-forme serait pour les variations d'exécution dans le comportement. Je fais souvent cela, reproduisant de petits bits de comportements existants dans mon code de production et en vérifiant que le comportement est comme prévu.

Mais pour ce cas ce que vous voulez vraiment, c'est un outil d'analyse statique, qui vérifie que le code que vos développeurs écrivent suit des conventions telles que celle-ci. C'est certainement un outil de construction valide. Cependant, à la recherche d'un outil d'analyse statique pour trouver ce que vous spécifiez ici pourrait être difficile. Je commencerais avec l'article Wikipedia Liste des outils pour analyse de code statique , dans le C / C ++ section.

Notez que le code que vous avez écrit n'est pas une "erreur", c'est simplement votre convention. C'est une très bonne convention, mais le compilateur ne doit pas vous limiter à cette convention. Et aucun outil d'analyse statique. Par conséquent, vous devrez trouver un qui vous permet de configurer ce qui est admissible et ce qui n'est pas.


2 commentaires

Malheureusement, CPPCheck ne fonctionne pas pour ce type d'erreur: "$ cppcheck main.cpp vérifiant main.cpp: ... aucune erreur trouvée"


Existe-t-il un moyen de configurer CPPCheck? Ça ne ressemble pas à ça. C'est ce que vous devrez faire de votre convention.



0
votes

in c ++ 11, vous pouvez utiliser

std :: is_concst (). Read_only ())> :: valeur

savoir sur la compilée (ou le temps d'exécution que vous le souhaitez) si ce type de retour est constitué.


0 commentaires