Logiciel donné où ...
- Le système se compose de quelques sous-systèmes
- Chaque sous-système se compose de quelques composants
- Chaque volet est mis en œuvre à l'aide de nombreuses classes
... J'aime écrire des tests automatisés de chaque sous-système ou d'un composant.
Je ne suis pas d'écrire un test pour chaque classe interne d'un composant (sauf dans la mesure où chaque classe contribue à la composante publique de fonctionnalités et qui est donc vérifiable/testé à partir de l'extérieur via le composant de l'API publique).
Quand je refactoriser la mise en œuvre d'un composant (qui je le fais souvent, dans le cadre de l'ajout de nouvelles fonctionnalités), donc je ne pas besoin de modifier un existant tests automatisés: parce que les tests dépendent uniquement de la composante publique de l'API, et les Api publiques sont généralement en cours d'expansion plutôt que modifié.
Je pense que cette politique contraste avec un document comme le Refactoring de Code de Test, qui dit des choses comme ...
- "... les tests unitaires ..."
- "... une classe de test pour chaque classe dans le système ..."
- "... test de code / code de production de rapport ... est idéalement considéré comme à l'approche d'un ratio de 1:1 ..."
... je suppose que je suis en désaccord avec (ou au moins ne pratique pas).
Ma question est, si vous êtes en désaccord avec ma politique, voulez-vous expliquer pourquoi? Dans quels cas est ce degré de tests insuffisants?
En résumé:
- Les interfaces publiques sont testés (et testés), et changent rarement (ils sont ajoutés à mais rarement modifié)
- Interne de l'Api sont cachés derrière les Api publiques, et peut être modifié sans avoir à réécrire les cas de test qui test les Api publiques
Note: certains de mes "cas de test" sont en fait mis en œuvre en tant que données. Par exemple, les cas de test de l'INTERFACE utilisateur sont constitués de fichiers de données qui contiennent des différentes entrées de l'utilisateur et le système des sorties. Les tests du système ayant des moyens de code de test qui lit chaque fichier de données, les replays l'entrée dans le système, et affirme qu'il devient le correspondant prévu de sortie.
Bien que j'ai rarement besoin de changer le code de test (parce que les Api sont généralement ajoutés à plutôt que modifié), je trouve que j'ai parfois (par exemple, deux fois par semaine) la nécessité de modifier certains fichiers de données existants. Cela peut se produire lorsque j'ai changer le système de sortie pour le mieux (c'est à dire une nouvelle fonctionnalité améliore l'existant de la sortie), ce qui pourrait causer un test existant pour "échouer" (parce que le code de test essaie seulement d'affirmer que la production n'a pas changé). Pour gérer ces cas je ne les suivants:
- Réexécutez le test automatisé suite une exécution drapeau, qui lui dit de ne pas faire valoir la sortie, mais au lieu de saisir la nouvelle sortie dans un nouveau répertoire
- Utiliser un visual diff pour voir l'outil de sortie de fichiers de données (c'est à dire que les cas de test), et de vérifier que ces changements sont bons et comme prévu, compte tenu de la nouvelle fonctionnalité
- Mettre à jour les tests existants par la copie des nouveaux fichiers de sortie de ce nouveau répertoire dans le répertoire à partir de laquelle les cas de tests sont exécutés sur l'écriture de la vieille tests)
Note: par "composant", je veux dire quelque chose comme "une DLL" ou une "assemblée" ... quelque chose qui est assez grand pour être visible sur une architecture ou d'un diagramme de déploiement du système, souvent mis en œuvre à l'aide de dizaines ou de 100 classes, et avec une API publique qui se compose de seulement 1 ou une poignée d'interfaces ... quelque chose qui peut être attribué à une équipe de développeurs (où un composant différent est attribué à un autre de l'équipe), et qui sera donc en fonction de Conway Droit d'avoir une relative stabilité de l'API publique.
Note de bas de page: L'article Orienté Objet les Tests: le Mythe et la Réalité dit,
Mythe: la boîte Noire est suffisant. Si vous faites attention à l'emploi des cas de test de la conception à l'aide de l'interface de classe ou spécification, vous pouvez être assuré que la classe a été entièrement levées. Blanche-boîte de test (à la recherche à un la méthode mise en œuvre pour la conception les tests) viole le concept même de l'encapsulation.
Réalité: OO structure de la matière, de la partie II. De nombreuses études ont montré que boîte noire des suites de test pensé pour être atrocement approfondie par les développeurs seulement l'exercice d'un tiers à une moitié des déclarations (sans parler de chemins d'accès ou de les états dans la mise en œuvre en vertu de test. Il y a trois raisons pour c'. Tout d'abord, les entrées ou les états sélectionné généralement exercice normal chemins d'accès, mais ne force pas possible des chemins et des etats. Deuxièmement, black-box test seul ne peut pas révéler de belles surprises. Supposons que nous avons testé toutes les spécifié comportements du système en cours de test. Pour être sûr il y a des pas non spécifié comportements que nous avons besoin de savoir si toutes les parties du système ont pas été exercé par la boîte noire suite de test. Le seul moyen d' des renseignements peuvent être obtenus est par code l'instrumentation. Troisièmement, il est souvent difficile l'exercice d'exception et gestion des erreurs sans examen de le code source.
Je dois ajouter que je suis en train de faire de la whitebox test fonctionnel: - je voir le code (dans la mise en œuvre) et j'écris des tests fonctionnels (dont le lecteur de l'API publique) d'exercer les diverses branches de code (les détails de la fonctionnalité de mise en œuvre).