Si vous concevez votre code pour faciliter les tests? Et si oui, comment concevoir
4 Réponses :
Dois-je mettre en œuvre les classes à l'aide d'une classe d'interface pure comme base afin de simplifier la création de faux objets de test? p>
- Cela me forcerait à faire beaucoup de méthodes virtuelles. Cela affectera-t-il la performance? LI> ul>
Une solution de contournement que j'utilise souvent est de templatiser la classe au lieu de la cacher derrière une interface. Ensuite, je peux passer des objets testés / simulaires en tant que paramètres de modèle lors du test et des objets réels autrement. De cette façon, le succès des performances des fonctions virtuelles est évité. P>
Modifier strong>
OK, un exemple simple: p>avec oop et interfaces, vous pouvez écrire une fonction telle que celle-ci: p>
xxx pré> Cette fonction prend un paramètre qui met en œuvre la
ibar code> interface et fait quelque chose avec elle. Si vous souhaitez transmettre une implémentation factice de maquette, vous écrivez simplement un faux objet qui hérite de
ibar code> et transmettez-le sur
foo code>. Simple et simple. P>
Mais vous pouvez obtenir la même chose avec des modèles: p>
xxx pré> ... et c'est tout. Le corps de
foo code> peut être à peu change. Tant que le type transmis à la fonction expose tous les membres dont nous avons besoin, cela fonctionnera, sans avoir à hériter formellement d'une classe d'interface et sans la surcharge de fonctions virtuelles et polymorphisme d'exécution. P> blockQuote>
Où puis-je lire plus sur la façon dont les classes templatiquent? Y a-t-il un motif qui décrit cela?
Pourquoi voulez-vous un motif pour tout ?? Jalf vous a montré une idée de laisser l'héritage (virtuel / polymorphisme) seul et utilisez plutôt les modèles C ++ (programmation générique). Donner des simulacres génériques (code de modèle) couvrirait des types possibles "tous" que vous utiliseriez (avec une seule fonction, à la place de nombreuses "méthodes virtuelles").
Bien sûr, le modèle peut rendre les dépendances du temps de compilation plus difficiles car leur mise en œuvre entre dans l'en-tête.
Non, je ne veux pas dire que j'ai besoin d'un motif. Je veux juste voir un exemple de ce qu'il veut dire. Je ne comprends pas ce que Jalf signifie juste du texte dans sa réponse.
@Matthieu m: La mise en œuvre peut ne pas avoir à aller dans l'en-tête. N'oubliez pas que le code de production réel n'instaine jamais le modèle avec un ensemble de types (les vrais, non moqueurs, non-test). La définition peut donc avoir besoin d'être visible dans une seule unité de traduction. Et vos tests pourraient alors peut-être inclure directement le .CPP directement. Votre code de test peut devenir un peu pirate de piratage, mais cela peut être un compromis utile - des tests unitaires ne doivent pas nécessairement être un code super élégant.
Je pense que la principale préoccupation devrait être ... p>
Ne concevez pas trop de em> à partir du début, puis écrivez un test, puis faites-le passer, mais pas plus que cela. Gardez vos fonctions très em> short. Regardez ce que vous avez fait et refacteur em> it. Si vous allez écrire un commentaire, mettez mieux le code en question à une fonction distincte avec un bon nom. P>
Et ne passez pas trop de temps à envisager de motifs, c'est beaucoup de science et de petit résultat, écrivez simplement un test d'abord et gardez votre code simple, puis, étonnamment, vous n'avez pas besoin d'écrire des tests pour cela, vous Je l'ai déjà fait. Et votre code fonctionne. P>
"Si vous allez écrire un commentaire, mieux mettre le code en question à une fonction distincte avec un bon nom" C'est très bon conseil.
La conception pour la qualification est vraiment un must. Cependant, vous devez également vous rendre compte que seule la "limite" doit être testable de manière autonome, il est parfaitement raisonnable que les composants internes dépendent de l'autre et ne doivent pas être testés isolément.
Vous pourriez être intéressé par ce Proposition de Stack-Exchange . Il est presque prêt à commencer la bêta, en a juste besoin de quelques autres.