Combien de tests par méthode?
Eh bien, le maximum théorique et hautement impraticable est la complexité de N-Path (supposons que les tests couvrent tous différentes manières dans le code;)). Le minimum est UN !. Par méthode publique , il ne teste pas les détails de l'implémentation, mais uniquement les comportements externes d'une classe (renvoie des valeurs et appelle d'autres objets).
Vous citez:
* Et l'idée de tester chacune de vos méthodes avec sa propre méthode de test (dans une relation 1-1) sera risible. *
et ensuite demander:
Donc, si créer un test pour chaque méthode est "risible", comment / quand avez-vous choisi ce pour quoi vous écrivez des tests?
Mais je pense que vous avez mal compris l'auteur ici:
L'idée d'avoir one test method
par one method in the class to test
ce que l'auteur appelle « risible ».
(Pour moi au moins) Il ne s'agit pas de "moins" mais de "plus"
Alors laissez-moi reformuler comme je l'ai compris:
Et l'idée de tester chacune de vos méthodes avec ONLY ONE METHOD (sa propre méthode de test dans une relation 1-1) sera risible.
Pour citer à nouveau votre devis:
Lorsque vous réalisez qu'il ne s'agit que de spécifier un comportement et non d'écrire des tests, votre point de vue change.
Lorsque vous pratiquez le TDD, vous ne pensez pas :
J'ai une méthode calculateX($a, $b);
et il faut un test testCalculcateX
qui teste TOUT sur la méthode.
Ce que TDD vous dit, c'est de réfléchir à ce que votre code DEVRAIT FAIRE :
J'ai besoin de calculer la plus grande des deux valeurs ( premier cas de test! ), Mais si $ a est inférieur à zéro, il devrait générer une erreur ( deuxième cas de test! ) Et si $ b est inférieur à zéro, il devrait ... ( troisième cas de test! ) et ainsi de suite.
Vous voulez tester des comportements, pas seulement des méthodes uniques sans contexte.
De cette façon, vous obtenez une suite de tests qui est une documentation pour votre code et explique VRAIMENT ce qu’elle est censée faire, peut-être même pourquoi :)
Comment décidez-vous pour quelle partie de votre code vous créez des tests unitaires?
Eh bien, tout ce qui finit dans le référentiel ou n'importe où près de la production nécessite un test. Je ne pense pas que l'auteur de vos citations serait en désaccord avec cela car j'ai essayé de le dire plus haut.
Si vous n'avez pas de test pour cela, il devient beaucoup plus difficile (plus coûteux) de changer le code, surtout si ce n'est pas vous qui le modifiez.
TDD est un moyen de vous assurer que vous avez des tests pour TOUT, mais tant que vous écrivez les tests, tout va bien. D'habitude, les écrire le même jour est utile, car vous n'allez pas le faire plus tard, n'est-ce pas? :)
Réponse aux commentaires:
une quantité décente de méthodes ne peuvent pas être testées dans un contexte particulier car elles dépendent ou dépendent d'autres méthodes
Il y a trois choses que ces méthodes peuvent appeler:
Méthodes publiques d'autres classes
Nous pouvons simuler d'autres classes afin d'y définir l'état. Nous contrôlons le contexte afin que ce ne soit pas un problème là-bas.
* Méthodes protégées ou privées sur le même *
Tout ce qui ne fait pas partie de l'API publique d'une classe n'est généralement pas testé directement.
Vous voulez tester le comportement et non l'implémentation et si une classe fait tout son travail dans une grande méthode publique ou dans plusieurs méthodes protégées plus petites appelées implémentation . Vous voulez pouvoir CHANGER ces méthodes protégées SANS toucher vos tests. Parce que vos tests vont casser si votre code change de comportement! C’est ce que vos tests sont là pour vous dire quand vous cassez quelque chose :)
Méthodes publiques sur la même classe
Cela n'arrive pas très souvent le fait? Et si cela ressemble à l'exemple suivant, il y a plusieurs façons de gérer cela:
$stuff = new Stuff();
$stuff->setBla(12);
$stuff->setFoo(14);
$stuff->execute();
Que les setters existent et ne font pas partie de la signature de la méthode execute est un autre sujet;)
Ce que nous pouvons tester ici, c'est si les exécutions explosent lorsque nous définissons des valeurs erronées. Cela setBla
lève une exception lorsque vous passez une chaîne peut être testé séparément, mais si nous voulons tester que ces deux valeurs autorisées (12 & 14) ne fonctionnent pas ensemble (pour une raison quelconque) que celle d'un cas de test.
Si vous voulez une "bonne" suite de tests, vous pouvez, en php, peut-être (!) Ajouter une @covers Stuff::execute
annotation pour vous assurer que vous ne générez une couverture de code que pour cette méthode et que les autres éléments qui ne font que configurer doivent être testés séparément vous voulez que).
Le problème est donc le suivant: vous devez peut-être d'abord créer une partie du monde environnant, mais vous devriez être capable d'écrire des scénarios de test significatifs qui ne couvrent généralement qu'une ou deux fonctions réelles (les ajusteurs ne comptent pas ici). Le reste peut être moqué à l'éther ou être testé en premier et ensuite invoqué (voir @depends
)
* Remarque: La question a été migrée depuis SO et concernait initialement PHP / PHPUnit, c'est pourquoi l'exemple de code et les références proviennent du monde php. Je pense que cela s'applique également à d'autres langages, car phpunit ne diffère pas beaucoup des autres xUnit. cadres de test.