Tests unitaires pour le code C ++ - Outils et méthodologie [fermé]


134

Je travaille sur un grand système C ++ qui est en développement depuis quelques années maintenant. Dans le cadre d'un effort pour améliorer la qualité du code existant, nous nous sommes engagés dans un grand projet de refactoring à long terme.

Connaissez-vous un bon outil qui peut m'aider à écrire des tests unitaires en C ++? Peut-être quelque chose de similaire à Junit ou Nunit?

Quelqu'un peut-il donner de bons conseils sur la méthodologie d'écriture des tests unitaires pour les modules qui ont été écrits sans les tests unitaires à l'esprit?


1
Consultez cette question: stackoverflow.com/questions/3150/…
Aardvark

Réponses:


83

L'application de tests unitaires au code hérité était la raison même pour laquelle Travailler efficacement avec le code hérité a été écrit. Michael Feathers est l'auteur - comme mentionné dans d'autres réponses, il a été impliqué dans la création de CppUnit et CppUnitLite .

texte alternatif


4
Ajout d'une vignette - voté. Le livre aide plus que n'importe quel outil.
Gishu

2
Je pense que CPPUnit pourrait simplifier l'écriture des tests. Nous utilisons CPPUnit, mais je ne suis pas satisfait. J'ai besoin de mettre à jour deux fichiers pour chaque test, et à mon avis, un test devrait être aussi simple à écrire que: 'TEST ("testname") {ASSERT (1 == 1);}' Le livre, par contre, est un must pour tout le monde, non seulement pour ceux qui travaillent avec le code hérité, mais aussi pour ceux qui le créent;)
daramarak

9
Depuis quand est l'héritage du C ++?!
Nils

9
Ce n'est pas que le C ++ soit hérité - si je me souviens bien, ce livre définit un projet hérité comme un projet pour lequel il n'y en a pas, ou très peu de tests unitaires. De tels projets ont tendance à être / difficiles / dans lesquels écrire des tests unitaires, car le développement piloté par les tests n'a jamais influencé la base de code de sorte qu'il soit trivial de les écrire.
Arafangion

7
@Nils: Comme le mentionne l'un des critiques d'Amazon du livre, «le code hérité est du code sans tests unitaires», ce qui est exactement le sujet de cette question.
David Johnstone

40

Google a récemment publié sa propre bibliothèque pour les tests unitaires des applications C ++, appelée Google Test.

Projet sur Google Code


1
est-il possible de l'utiliser avec VC ++
yesraaj

Cela semble assez correct, en particulier la façon dont ils doivent ajouter une description à chaque assertion. Par contre, je préfère personnellement avoir une classe de test unitaire au lieu de macros qui ne ressemblent vraiment pas à des classes.
Wernight

3
un autre point intéressant est les possibilités de se moquer: code.google.com/p/googlemock
Philipp

Je trouve cela BEAUCOUP plus agréable que CPPUNIT qui nécessite des tonnes de macros et de fichiers magiques pour que les tests fonctionnent
paulm

30

Découvrez une excellente comparaison entre plusieurs suites disponibles. L'auteur de cet article a développé plus tard UnitTest ++ .

Ce que j'aime particulièrement à ce sujet (mis à part le fait qu'il gère bien les exceptions, etc.), c'est qu'il y a une quantité très limitée d '«administration» autour des cas de test et de la définition des appareils de test.


2
N'est-ce pas notre erreur fondamentale? Il a un bon aperçu des projets disponibles - mais au lieu de les améliorer, il commence les siens.
peterchen

@peterchen: oui; mais alors UnitTest ++ est si petit et léger qu'il a de la valeur en tant que projet séparé - il est très facile de démarrer.
TimStaley

24

Boost a une bibliothèque de test qui prend en charge les tests unitaires. Cela vaut peut-être la peine de vérifier.


4
Je peux recommander cette excellente boîte à outils.
Rob

1
Oui, le boost est la voie à suivre. Pas de frais généraux, testez et partez! Je travaillais en fait sur mon propre cadre dans le désespoir quand boost est venu à mon secours. Merci boost (pour tout!)
Daramarak

Vous pouvez consulter un article que j'ai écrit introduction Boost Unit Testing beroux.com/english/articles/boost_unit_testing
Wernight

21

Noel Llopis de Games From Within est l'auteur de Exploring the C ++ Unit Testing Framework Jungle , une évaluation complète (mais désormais datée) des différents frameworks de test unit C ++, ainsi qu'un livre sur la programmation de jeux.

Il a utilisé CppUnitLite pendant un certain temps, corrigeant diverses choses, mais s'est finalement associé à un autre auteur de bibliothèque de tests unitaires et a produit UnitTest ++ . Nous utilisons UnitTest ++ ici, et je l'aime beaucoup, jusqu'à présent. Il a (pour moi) le juste équilibre de puissance avec un faible encombrement.

J'ai utilisé des solutions locales, CxxTest (qui nécessite Perl) et boost :: test. Lorsque j'ai implémenté les tests unitaires ici, dans mon travail actuel, cela se résumait à UnitTest ++ vs boost :: test.

J'aime vraiment la plupart des bibliothèques boost que j'ai utilisées, mais à mon humble avis, boost :: test est un peu trop lourd. Je n'ai surtout pas aimé qu'il vous oblige (AFAIK) à implémenter le programme principal du harnais de test en utilisant une macro boost :: test. Je sais que ce n'est pas du TDD "pur", mais parfois nous avons besoin d'un moyen d'exécuter des tests à partir d'une application GUI, par exemple lorsqu'un indicateur de test spécial est passé sur la ligne de commande et que boost :: test ne peut pas prendre en charge ce type du scénario.

UnitTest ++ était le framework de test le plus simple à configurer et à utiliser que j'ai rencontré dans mon expérience (limitée).


17

J'utilise l'excellente bibliothèque Boost.Test en conjonction avec une tortue beaucoup moins connue mais tellement géniale bibliothèque : une bibliothèque d'objets fictifs basée sur Boost.

Comme un exemple de code parle mieux que des mots, imaginez que vous aimeriez tester un calculatorobjet qui fonctionne sur une viewinterface (c'est l'exemple introductif de Turtle):

// declares a 'mock_view' class implementing 'view'
MOCK_BASE_CLASS( mock_view, view )
{
    // implements the 'display' method from 'view' (taking 1 argument)
    MOCK_METHOD( display, 1 )                   
};

BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
    mock_view v;
    calculator c( v );

    // expects the 'display' method to be called once with a parameter value equal to 0
    MOCK_EXPECT( v, display ).once().with( 0 ); 

    c.add( 0, 0 );
}

Voyez à quel point il est facile et verbeux de déclarer une attente sur l'objet simulé? De toute évidence, le test échoue si les attentes ne sont pas satisfaites.


14

Je viens de pousser mon propre cadre, CATCH , là-bas. Il est encore en développement mais je pense qu'il surpasse déjà la plupart des autres frameworks. Différentes personnes ont des critères différents, mais j'ai essayé de couvrir la plupart des domaines sans trop de compromis. Jetez un œil à mon article de blog lié pour un avant-goût. Mes cinq principales fonctionnalités sont:

  • En-tête uniquement
  • Enregistrement automatique des tests basés sur la fonction et la méthode
  • Décompose les expressions C ++ standard en LHS et RHS (vous n'avez donc pas besoin de toute une famille de macros d'assert).
  • Prise en charge des sections imbriquées dans un appareil basé sur la fonction
  • Tests de noms en langage naturel - les noms de fonctions / méthodes sont générés

Il a également des liaisons Objective-C.


4
doctest est ma réimplémentation de Catch avec un grand accent sur la vitesse de compilation - consultez la FAQ pour voir en quoi elles sont différentes
onqtam

9

CxxTest est un framework JUnit / CppUnit / xUnit-like léger, facile à utiliser et multiplateforme pour C ++.




6

Je suis actuellement à la recherche d'un test unitaire et d'un framework simulé pouvant être utilisé dans notre entreprise pour une base de code de longue durée. Comme vous le savez, la liste des frameworks de tests unitaires pour c ++ est longue, j'ai donc appliqué quelques filtres pour la réduire à une main complète qui peut être examinée de plus près. Le premier critère de filtrage était qu'il devait être gratuit. Le deuxième critère était l'activité du projet. J'ai également cherché des frameworks moqueurs car vous en avez besoin si vous voulez écrire des tests unitaires.

Je suis venu avec la liste suivante (approximativement) triée par activité, l'activité la plus élevée en haut:

  • GoogleTest / GoogleMock: de nombreux contributeurs et utilisé par Google lui-même. Ce sera probablement ici pendant un certain temps et recevra des mises à jour. Pour ma base de code privée, je passerai à cette combinaison dans l'espoir de sauter dans le train le plus rapide.

  • BoostTest + Turtle: Pas souvent mis à jour, mais le cadre de test fait partie de boost, il doit donc être maintenu. La tortue, par contre, est entretenue principalement par un gars, mais elle a une activité répréhensible, donc elle n'est pas morte. J'ai fait presque toute mon expérience de test avec cette combinaison car nous avons déjà utilisé la bibliothèque boost lors de mon travail précédent et je l'utilise actuellement pour mon code privé.

  • CppUTest: fournit des tests et des simulations. Ce projet a été actif de 2008 à 2015 et a une activité récente assez importante. Cette découverte a été un peu surprenante car beaucoup de projets avec beaucoup moins d'activité reviennent plus souvent lors de la recherche sur le Web (comme CppUnit qui a eu sa dernière mise à jour en 2013). Je n'ai pas approfondi cela, donc je ne peux rien dire sur les détails. Edit (16.12.2015): J'ai récemment essayé cela et j'ai trouvé que ce framework était un peu maladroit et "C-élégant", en particulier lors de l'utilisation des classes simulées. En outre, il semblait avoir une plus petite variété d'assertions que d'autres cadres. Je pense que sa principale force est qu'il peut être utilisé avec des projets purs en C.

  • QTest: La bibliothèque de test fournie avec le framework Qt. La maintenance devrait être garantie pendant un certain temps, mais je l'utilise plutôt comme une bibliothèque de support, car l'enregistrement de test est plus maladroit dans l'OMI que dans d'autres frameworks. Autant que je sache, cela vous oblige à avoir un test-exe par appareil de test. Mais les fonctions d'assistance de test peuvent être utiles lors du test du code Qt-Gui. Il n'y a pas de moquerie.

  • Catch: Il a une activité récente mais est principalement développé par un seul gars. La bonne chose à propos de ce framework est l'approche alternative des fixtures qui vous permet d'écrire du code de fixture réutilisable dans le test lui-même. Il vous permet également de définir les noms de test sous forme de chaînes, ce qui est bien lorsque vous avez tendance à écrire des phrases entières comme noms de test. Je souhaite que ce style soit déchiré et mis dans googleTest ;-)

Cadres simulés

Le nombre de frameworks fictifs est beaucoup plus petit que le nombre de frameworks de test, mais voici ceux que j'ai trouvé pour avoir une activité récente.

  • Hippomock : Actif à partir de 2008 unitl maintenant mais seulement avec une faible intensité.

  • FakeIt : Actif à partir de 2013 unitl maintenant mais plus ou moins développé par un seul gars.

Conclusion

Si votre base de code est pour le long terme, choisissez entre BoostTest + Turtle et GoogleTest + GoogleMock . Je pense que ces deux-là auront un entretien à long terme. Si vous n'avez qu'une base de code de courte durée, vous pouvez essayer Catch qui a une belle syntaxe. Ensuite, vous devrez également choisir un cadre moqueur. Si vous travaillez avec Visual Studio, vous pouvez télécharger des adaptateurs de test-runner pour BoostTest et GoogleTest, qui vous permettront d'exécuter les tests avec l'interface graphique de test runner intégrée à VS.


3

Voir aussi les réponses à la question étroitement liée "choisir un outil / framework de test unitaire C ++", ici


3

Il existe également TUT , Template-Unit-Test, un framework basé sur des modèles. Sa syntaxe est maladroite (certains l'ont qualifiée d'abus de modèle), mais son principal avantage est que tout est contenu dans un seul fichier d'en-tête .

Vous trouverez ici un exemple de test unitaire écrit avec TUT .


2
J'ai mis en place une bibliothèque d'en-tête uniquement fournissant des macros enveloppant la fonction TUT et le code de déclinaison de test à la fois pour le simplifier et fournir des informations sur les fichiers et les numéros de ligne en cas d'échec. Voici un lien vers un article avec des exemples de la différence de sortie et de code ainsi qu'un lien vers le projet sur github: codecrafter.wordpress.com/2012/12/19/tutadapter1
Josh Heitzman

2

J'ai essayé CPPunit et ce n'est pas très convivial.

La seule alternative que je connaisse est d'utiliser C ++. NET pour envelopper vos classes C ++ et écrire des tests unitaires avec l'un des frameworks de test unitaire .NET (NUnit, MBUnit, etc.)



1

Michael Feathers d'ObjectMentor a joué un rôle déterminant dans le développement de CppUnit et CppUnitLite.

Il recommande maintenant CppUnitLite



1

Jetez un œil à cfix ( http://www.cfix-testing.org ), il est spécialisé pour le développement Windows C / C ++ et prend en charge les tests unitaires en mode utilisateur et en mode noyau.


Merci d'avoir partagé. J'ai récemment commencé à utiliser cfix à des fins de test. Je cherchais un moyen de visualiser la pile d'appels en cas de cas de test réussis et échoués. Y a-t-il moyen dans cfix d'y parvenir?
TryToLearn

1

Si vous utilisez Visual Studio 2008 SP1, je vous recommande vivement d'utiliser MSTest pour écrire les tests unitaires. J'utilise ensuite Google mock pour écrire les mocks. L'intégration avec l'IDE est idéale et permet et ne supporte pas la surcharge de CPPunit en termes d'édition de trois endroits pour l'ajout d'un test.


1

Je pense que VisualAssert fait un excellent travail dans l'intégration VS. Il vous permet d'exécuter et de déboguer les tests de VS et vous n'avez pas besoin de créer un exécutable pour exécuter les tests.



En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.