Considère ceci:
public function polynominal($a, $b, $c, $d)
{
return $a * pow($x, 3) + $b * pow($x, 2) + $c * $x + $d;
}
Supposons que vous écriviez divers tests pour la fonction ci-dessus et que vous prouviez à vous-même et aux autres que cela "fonctionne".
Pourquoi alors ne pas retirer ces tests et vivre heureux pour toujours? Mon argument est que certaines fonctions n'ont pas besoin d'être testées en permanence après que leur efficacité ait été prouvée. Je cherche des contre-points qui indiquent, oui, ces fonctions doivent encore être testées, car: ... ou que, oui, elles n'ont pas besoin d'être testées ...
php
unit-testing
testing
tdd
Dennis
la source
la source
override_function('pow', '$a,$b', 'return $a * $b;');
dans la raison ... ou n'essayera pas de le réécrire pour gérer des nombres complexes.(($a*$x + $b)*$x + $c)*$x + $d
est facile de se tromper, mais est souvent beaucoup plus rapide. Ce n’est pas parce que vous pensez que cela ne changera pas.Réponses:
Les tests de régression
Tout est question de test de régression .
Imaginez le prochain développeur qui examine votre méthode et remarque que vous utilisez des nombres magiques. On lui a dit que les nombres magiques sont diaboliques, il a donc créé deux constantes, une pour le numéro deux, l'autre pour le numéro trois - il n'y a rien de mal à faire ce changement; ce n'est pas comme s'il modifiait votre implémentation déjà correcte.
Etre distrait, il inverse deux constantes.
Il valide le code et tout semble bien fonctionner, car aucun test de régression n'est exécuté après chaque validation.
Un jour (peut-être des semaines plus tard), quelque chose se casse ailleurs. Et par ailleurs, je veux dire dans l'emplacement complètement opposé de la base de code, ce qui semble n'avoir rien à voir avec la
polynominal
fonction. Des heures de débogage douloureux mènent au coupable. Pendant ce temps, l'application continue d'échouer en production, causant de nombreux problèmes à vos clients.Garder les tests originaux que vous avez écrits pourrait éviter une telle douleur. Le développeur distrait commettrait le code et verrait presque immédiatement qu'il avait cassé quelque chose; un tel code n'atteindra même pas la production. Les tests unitaires seront en outre très précis sur l'emplacement de l'erreur . Le résoudre ne serait pas difficile.
Un effet secondaire ...
En fait, la plupart des refactorisations sont fortement basées sur des tests de régression. Faites un petit changement. Tester. Si ça passe, tout va bien.
L'effet secondaire est que si vous n'avez pas de test, pratiquement toute refactorisation devient un risque énorme de casser le code. Étant donné le nombre de cas, il est déjà difficile d’expliquer à la direction que la refactorisation doit être effectuée. Il serait encore plus difficile de le faire après que vos précédentes tentatives de refactoring aient introduit plusieurs bogues.
En proposant une suite complète de tests, vous encouragez la refactorisation et, par conséquent, un code plus propre. Sans risque, il devient très tentant de refactoriser davantage, sur une base régulière.
Changements dans les exigences
Un autre aspect essentiel est que les exigences changent. Vous serez peut-être invité à gérer des nombres complexes et vous devrez soudainement effectuer une recherche dans votre journal de contrôle de version pour rechercher les tests précédents, les restaurer et commencer à ajouter de nouveaux tests.
Pourquoi tout ce tracas? Pourquoi supprimer des tests pour les ajouter plus tard? Vous auriez pu les garder en premier lieu.
la source
Parce que rien n'est si simple qu'il ne peut y avoir de bugs.
Votre code, à première vue, semble être exempt de bogues. Il s’agit en fait d’une simple représentation programmatique d’une fonction polynomiale.
Sauf qu'il a un bug ...
$x
n'est pas défini comme une entrée dans votre code et, selon la langue, le runtime ou la portée, votre fonction peut ne pas fonctionner, entraîner des résultats non valides ou bloquer un vaisseau spatial .Addenda:
Bien que vous considériez votre code sans bug pour le moment, il est difficile de dire combien de temps il reste. On pourrait faire valoir qu’écrire un test pour un élément de code aussi trivial n’en vaut pas la peine, mais le fait que le test ait déjà été écrit et son effacement supprime un dispositif de sécurité tangible.
Il est à noter que les services de couverture de code (tels que coveralls.io) donnent une bonne indication de la couverture fournie par une suite de tests. En couvrant chaque ligne de code, vous donnez une mesure décente de la quantité (sinon de la qualité) des tests que vous effectuez. Combinés à de nombreux petits tests, ces services vous indiquent au moins où ne pas rechercher un bogue lorsque cela se produit.
En fin de compte, si vous avez déjà un test écrit, conservez-le . Parce que le gain de temps ou d'espace résultant de sa suppression sera probablement bien inférieur à la dette technique ultérieurement si un bogue survient.
la source
Oui. Si nous pouvions dire avec 100% de confiance, avec certitude: cette fonction ne sera jamais modifiée et ne fonctionnera jamais dans un contexte susceptible de l’échouer. Si nous pouvions dire cela, nous pourrions abandonner les tests et économiser quelques millisecondes à chaque fois. Construction de CI.
Mais nous ne pouvons pas. Ou, nous ne pouvons pas avec beaucoup de fonctions. Et il est plus simple d’avoir pour règle de faire tous les tests en permanence que de s’efforcer de déterminer exactement le seuil de confiance dont nous sommes satisfaits et le degré de confiance que nous avons dans l’immuabilité et l’infaillibilité d’une fonction donnée.
Et le temps de traitement est bon marché. Ces millisecondes économisées, même multipliées à de nombreuses reprises, ne totalisent pas assez pour justifier de prendre le temps avec chaque fonction pour demander: avons-nous suffisamment confiance en nous pour qu'il ne soit plus nécessaire de les tester à nouveau?
la source
Tout ce qui est dit dans les autres réponses est correct, mais je vais en ajouter une de plus.
Documentation
Les tests unitaires, s'ils sont bien écrits, peuvent expliquer aux développeurs ce que fait une fonction, quelles sont ses attentes en matière d'entrées / sorties et, plus important encore, quel comportement on peut en attendre.
Cela peut faciliter la détection d'un bogue et réduire la confusion.
Tout le monde ne se souvient pas des polynômes, de la géométrie ou même de l'algèbre :) Mais un bon test unitaire enregistré dans le contrôle de version s'en souviendra pour moi.
Pour un exemple d’utilité en tant que documentation, consultez l’introduction de Jasmine: http://jasmine.github.io/edge/introduction.html Donnez-lui quelques secondes à charger, puis faites défiler vers le bas. L'ensemble de l'API Jasmine sera documentée sous forme de sortie de test unitaire.
[Mise à jour basée sur les commentaires de @Warbo] Les tests sont également garantis, car s'ils échouent, ils échoueront, ce qui provoquera généralement un échec de construction si le CI est utilisé. La documentation externe change indépendamment du code et n'est donc pas nécessairement à jour.
la source
Vérification de la réalité
J'ai été dans des environnements difficiles où les tests sont "une perte de temps" lors de la budgétisation et du calendrier, puis "un élément fondamental de l'assurance qualité" une fois que le client a affaire à des bugs, mon avis est donc plus fluide que les autres.
Vous avez un budget. Votre travail consiste à obtenir le meilleur produit possible avec ce budget, quelle que soit la définition du terme "meilleur" que vous pouvez rassembler (ce n'est pas un mot facile à définir). Fin de l'histoire.
Le test est un outil dans votre inventaire. Vous devriez l’utiliser, car c’est un bon outil , qui économise des millions, voire des milliards de dollars depuis longtemps. Si vous en avez l'occasion, vous devriez ajouter des tests à ces fonctions simples. Cela peut sauver votre peau un jour.
Mais dans le monde réel, avec des contraintes de budget et de calendrier, cela peut ne pas arriver. Ne vous faites pas l'esclave de la procédure. Les fonctions de test sont utiles, mais à un moment donné, vos heures de travail seront peut-être mieux consacrées à la rédaction de la documentation pour développeurs en mots, plutôt qu'en code, afin que le développeur suivant n'ait pas besoin de autant de tests. Ou alors, il serait peut-être préférable de refactoriser la base de code pour ne pas avoir à maintenir une bête aussi difficile. Ou peut-être préféreriez-vous plutôt passer votre temps à discuter du budget et du calendrier avec votre supérieur hiérarchique afin qu'il comprenne mieux ce à quoi il aspirait lors de la prochaine ronde de financement.
Le développement de logiciels est un équilibre. Comptez toujours le coût d'opportunité de tout ce que vous faites pour vous assurer qu'il n'y a pas de meilleure façon de dépenser votre temps.
la source
Oui, gardez les tests, maintenez-les en marche et maintenez-les en réussite
Les tests unitaires sont là pour vous protéger (et protéger les autres) de vous-même (et d'eux-mêmes).
Pourquoi garder les tests une bonne idée?
la source
Documentation développeur
Documentation utilisateur
la source