web-dev-qa-db-fra.com

Test de l'unité C ++: Que tester?

TL; DR

Écrire de bons tests utiles est difficile et a un coût élevé en C++. Pouvez-vous expérimenter les développeurs partager votre justification sur quoi et quand testez-vous?

longue histoire

J'avais l'habitude de faire du développement axé sur les tests, toute votre équipe en fait, mais cela n'a pas bien fonctionné pour nous. Nous avons de nombreux tests, mais ils ne semblent jamais couvrir les cas où nous avons des bugs et des régressions réels - qui se produisent généralement lorsque des parts interagissent, non de leur comportement isolé.

Ceci est souvent si difficile à tester sur le niveau de l'unité que nous avons arrêté de faire TDD (à l'exception des composants où il accélère réellement le développement), et a plutôt investi plus de temps à augmenter la couverture de test d'intégration. Bien que les petits tests de l'unité n'ont jamais attrapé de vrais bugs et étaient essentiellement des frais de maintenance, les tests d'intégration ont vraiment valable l'effort.

Maintenant, j'ai hérité d'un nouveau projet et je me demande comment aller le tester. C'est une application native C++/OpenGL, alors les tests d'intégration ne sont pas vraiment une option. Mais les tests unitaires en C++ sont un peu plus difficiles que dans Java (vous devez faire des choses explicitement virtual), et le programme n'est pas extrêmement orienté objet, donc je peux " t ma moqueur/supporter des trucs.

Je ne veux pas déchirer et oo-ize le tout simplement pour écrire des tests pour des tests d'écriture. Donc, je vous demande: qu'est-ce que je devrais écrire des tests? par exemple.:

  • Fonctions/classes que je prévois de changer fréquemment?
  • Fonctions/classes plus difficiles à tester manuellement?
  • Fonctions/classes faciles à tester déjà?

J'ai commencé à enquêter sur des bases respectueuses de Code C++ pour voir comment elles vont des tests. À l'heure actuelle, je regarde dans le code source du chrome, mais je trouve qu'il est difficile d'extraire leur justification de test du code. Si quelqu'un en a un bon exemple ou post sur la popularité des utilisateurs C++ populaires (gars du comité, des auteurs de livres, Google, Facebook, Microsoft, ...) Approchez-le, cela serait très utile.

Mise à jour

J'ai cherché mon chemin autour de ce site et le Web depuis l'écriture de cela. Trouvé de bonnes choses:

Malheureusement, tous sont plutôt java/c # centriques. Écrire beaucoup de tests dans Java/C # n'est pas un gros problème, de sorte que les avantages exercent généralement les coûts.

Mais comme je l'ai écrit ci-dessus, c'est plus difficile en C++. Surtout si votre base de code n'est pas - SO-OO, vous devez dégager de manière sévère les choses pour obtenir une bonne couverture de test unitaire. Par exemple: l'application que j'ai héritée a un espace de nom Graphics une couche mince au-dessus de OpenGL. Afin de tester l'une des entités - qui utilisent tous ses fonctions directement - je devrais transformer cela en une interface et une classe et de l'injecter dans toutes les entités. C'est juste un exemple.

Ainsi, lorsque vous répondez à cette question, veuillez garder à l'esprit que je dois faire un investissement assez gros pour écrire des tests.

20
futlib

Eh bien, le test unitaire n'est qu'une partie. Les tests d'intégration vous aident avec le problème de votre équipe. Les tests d'intégration peuvent être écrits pour toutes sortes d'applications, également pour les applications Native et OpenGL. Vous devriez vérifier "Software de l'objet en croissance guidée par des tests" par Steve FreeMann et Nat Pryce (par exemple, http://www.amazon.com/groende-Object-oriented-software-Guided-Signature/0321503627 ). Il vous mène étape par étape grâce au développement d'une application avec interface graphique et communication réseau.

Les logiciels de test qui n'étaient pas testés sont une autre histoire. Vérifiez que Michael Plumes "fonctionne efficacement avec le code hérité" (http://www.amazon.com/working-effective-legacy-michael-feathers/dp/0131177052).

5
EricSchaefer

Je n'ai pas fait TDD en C++, donc je ne peux pas commenter cela, mais vous êtes censé tester le comportement attendu de votre code. Bien que la mise en œuvre puisse changer, le comportement devrait (généralement?) Restez le même. Dans Java\C # Centric World, cela signifierait que vous ne testerez que les méthodes publiques, des tests d'écriture pour le comportement attendu et de le faire avant la mise en œuvre (ce qui est généralement mieux dit mieux que fait :)).

2
Dante

C'est une honte TDD "ne fonctionnait pas bien pour toi." Je pense que c'est la clé pour comprendre où tourner. Revisitez et comprenez comment TDD n'a pas fonctionné, que pourriez-vous avoir fait mieux, pourquoi y a-t-il eu des difficultés?.

Donc, bien sûr, vos tests de l'unité n'ont pas attrapé les bugs que vous avez trouvés. C'est un peu le point. :-) Vous n'avez pas trouvé ces bugs parce que vous les avez empêchés de se produire en premier lieu en donnant réflexion sur la manière dont les interfaces devraient fonctionner et comment s'assurer qu'ils ont été testés correctement.

Pour répondre, vous avez interrogé, comme vous avez conclu, le code de test unitaire qui n'est pas conçu à tester est difficile. Pour le code existant, il peut être plus efficace d'utiliser un environnement de test fonctionnel ou d'intégration plutôt que d'un environnement de test unitaire. Testez le système en mettant l'accent sur des zones spécifiques.

Bien sûr, le nouveau développement bénéficiera de TDD. À mesure que de nouvelles fonctionnalités sont ajoutées, le refactoring pour TDD pourrait aider à tester le nouveau développement, tout en permettant de développer un nouveau test d'unité pour les fonctions héritées.

2
Bill Door