- Je parle de tests unitaires au sens TDD. ("Intégration" non automatisée, ou ce que vous aimez appeler des tests.)
- Code hérité comme dans: (C ++) code sans tests. (voir: Michael Feathers travaille efficacement avec Legacy Code )
- Mais aussi le code hérité comme dans: Code avec lequel notre équipe travaille depuis 10-5 ans, donc nous avons très souvent une assez bonne idée de l'endroit où mettre les choses pour changer quelque chose.
- Nous avons des tests unitaires en place (via Boost.Test) pour certains modules qui sont venus plus tard ou qui ont été un ajustement "naturel" pour les tests unitaires (conteneurs spécifiques aux applications courantes, trucs de chaîne, aides réseau, etc.)
- Nous n'avons pas encore de tests d'acceptation automatisés appropriés.
Maintenant, récemment, j'ai eu le «plaisir» de mettre en œuvre 3 nouvelles fonctionnalités destinées aux utilisateurs.
Chacun d'eux m'a pris environ 1 à 2 heures pour me familiariser avec les parties de code que je devais changer, 1 à 2 heures pour implémenter le (petit) code que je devais changer et encore 1 à 2 heures pour m'assurer que l'application a fonctionné correctement par la suite et a fait ce qu'il était censé faire.
Maintenant, j'ai vraiment ajouté peu de code. (Je pense qu'une méthode et quelques lignes d'appel pour chaque fonctionnalité.)
La factorisation de ce code (via l'une des méthodes suggérées dans WEwLC ), de sorte qu'un test unitaire aurait eu du sens (et n'aurait pas été une tautologie complète) aurait facilement pris encore 2 à 4 heures, sinon plus. Cela aurait ajouté 50% à 100% de temps à chaque fonctionnalité, sans aucun avantage immédiat, comme
- Je n'avais pas besoin du test unitaire pour comprendre quoi que ce soit sur le code
- Les tests manuels représentent la même quantité de travail, car j'ai encore besoin de tester si le code est correctement intégré dans le reste de l'application.
Certes, si , plus tard, "quelqu'un" venait et touchait ce code, il pourrait théoriquement bénéficier de ce test unitaire. (Seulement en théorie, car cette île de code testée vivrait dans un océan de code non testé.)
Donc, "cette fois-ci", j'ai choisi de ne pas faire le travail difficile de l'ajout d'un test unitaire: les modifications de code pour mettre ces choses sous test auraient été beaucoup plus complexes que les modifications de code pour obtenir la fonctionnalité correctement (et proprement) implémentée.
Est-ce quelque chose de typique pour un code hérité fortement couplé? Suis-je paresseux / fixons-nous les mauvaises priorités en équipe? Ou suis-je prudent, ne testant que des choses où les frais généraux ne sont pas trop élevés?
la source
Réponses:
Il faut être pragmatique face à ces situations. Tout doit avoir une valeur commerciale, mais l'entreprise doit vous faire confiance pour juger de la valeur du travail technique. Oui, les tests unitaires présentent toujours un avantage, mais cet avantage est-il suffisamment important pour justifier le temps passé?
Je me disputerais toujours sur le nouveau code mais, sur le code hérité, vous devez faire un jugement.
Êtes-vous souvent dans ce domaine du code? Ensuite, il y a lieu d'améliorer continuellement. Faites-vous un changement significatif? Ensuite, il y a un cas où c'est déjà un nouveau code. Mais si vous créez un code à une ligne dans un domaine complexe qui ne sera probablement pas touché à nouveau pendant un an, bien sûr, le coût (sans parler du risque) de la réingénierie est trop élevé. Tapez simplement votre ligne de code et allez prendre une douche rapidement.
Règle générale: pensez toujours à vous-même: " Est-ce que je pense que l'entreprise profite davantage de ce travail technique que je pense que je devrais faire que du travail qu'elle a demandé et qui sera par conséquent retardé? "
la source
Le gain des tests unitaires au sens TDD est d'obtenir quelque chose qui se tient tout seul, sans avoir besoin d'une tradition orale construite au fil des ans par une équipe stable.
C'est une grande chance que la même équipe travaille sur le même projet depuis si longtemps. Mais cela finira par changer. Les gens tombent malades, s'ennuient ou sont promus. Ils bougent, prennent leur retraite ou meurent. Les nouveaux viennent avec de nouvelles idées et l'envie de refaçonner tout ce qu'ils ont appris à l'école. Les entreprises sont vendues et achetées. Les politiques de gestion changent.
Si vous voulez que votre projet survive, vous devez le préparer aux changements.
la source
L'écriture de tests unitaires permet de pérenniser votre code. Si la base de code n'a pas de tests, vous devez ajouter de nouveaux tests pour toutes les nouvelles fonctionnalités, car cela rend ce morceau de code juste un peu plus robuste.
Je trouve que l'ajout de tests, même dans du code hérité, est bénéfique à moyen et long terme. Si votre entreprise ne se soucie pas du moyen à long terme, je chercherais une autre entreprise. De plus, je ne pense pas qu'il soit plus long de tester manuellement que de rédiger un test unitaire défini. Si c'est le cas, vous devez pratiquer le kata de code axé sur l'écriture de tests.
la source
Il est certain que les meilleures pratiques vous obligent à tester unitaire tout code que vous modifiez. Le codage dans le monde réel implique cependant beaucoup de compromis, le temps et les matériaux sont finis.
Ce que vous devez faire est d'évaluer le coût en termes réels de correction de bugs et de modifications sans tests unitaires. Vous pouvez ensuite évaluer l'investissement dans la création de ces tests. Les tests unitaires réduisent considérablement le coût des travaux futurs mais ont un prix maintenant.
En fin de compte, si votre système est rarement modifié, cela peut ne pas valoir la peine d'écrire des tests unitaires, mais s'il est soumis à des changements réguliers, cela en vaudra la peine.
la source
Toutes ces petites décisions rationnelles de ne pas créer de tests accumulent une dette technique paralysante qui reviendra vous hanter lorsque quelqu'un partira et qu'une nouvelle embauche devra arriver et se mettre au courant.
Oui, l'écriture des tests unitaires aurait pu coûter 2-3 heures de plus, mais si le code est renvoyé des tests, vous devrez tout tester à nouveau manuellement et documenter vos tests à nouveau - vous le faites, n'est-ce pas? Sinon, comment sait-on ce que vous avez testé et quelles valeurs vous avez utilisées?
Les tests unitaires documentent le comportement attendu du code, les données de test utilisées pour vérifier la fonctionnalité et donnent aux nouveaux codeurs une assurance raisonnable qu'ils n'ont pas cassé quelque chose lors des modifications.
Aujourd'hui, cela coûte quelques heures de plus que les tests manuels, mais vous testez chaque fois que vous effectuez des modifications, ce qui vous fait gagner des heures pendant la durée de vie du code.
Cependant, si vous savez que le code sera retiré dans quelques années, tout ce que j'ai dit est que vous ne finirez pas de mettre des tests dans le code et que cela ne sera jamais remboursé.
la source
La valeur des tests unitaires ne réside pas seulement dans le test d'une nouvelle fonctionnalité lorsqu'elle est développée. L'avantage des tests unitaires est principalement acquis à l'avenir.
Oui, vous devrez peut-être passer ce qui semble être un temps excessif pour rendre votre code hérité testable.
Mais si vous ne le faites pas, vous passerez, ou vous devriez certainement , passer de très nombreuses heures à tester la fonctionnalité. Pas seulement sur son développement initial, mais avec chaque nouvelle version de votre logiciel. Sans tests unitaires et autres formes de tests automatisés, vous n'avez pas d'autre option que de passer de nombreuses heures de tests manuels pour vous assurer que votre fonctionnalité n'a pas été interrompue par inadvertance, même si cette fonctionnalité elle-même n'a pas été modifiée.
la source