web-dev-qa-db-fra.com

Qu'est-ce qu'un test unitaire de boîte noire?

J'ai récemment passé mon examen final pour un cours de génie logiciel pour mon programme de maîtrise et l'une des questions de l'examen était la suivante:

Unit Testing is considered:
a. White-box Testing
b. Black-box Testing
c. Either

Au cours de mes 7 années d'expérience en développement de logiciels, les tests unitaires ont toujours adopté une approche de boîte blanche. Le testeur a toujours eu une connaissance complète de la mise en œuvre de l'unité lors de la rédaction des tests. Les tests de la boîte noire sont toujours venus plus tard sous la forme de tests d'intégration, de système et d'acceptation.

Cependant, la bonne réponse à l'examen (selon le professeur) est que les tests unitaires peuvent être des tests en boîte blanche ou noire.

J'ai fait quelques recherches, et il semble que de nombreux cas de "tests unitaires de boîte noire" sont utilisés pour décrire une approche test-first où les tests unitaires sont écrits avant le code. Cependant, à mon avis, il s'agit toujours de tests en boîte blanche. Bien que l'implémentation n'existe pas encore, celui qui écrit le test a généralement une assez bonne idée de la façon dont le code source va être implémenté.

Quelqu'un peut-il m'expliquer comment fonctionnent les tests unitaires en boîte noire (si c'est vraiment une chose) et en quoi ils diffèrent des tests unitaires en boîte blanche?

11
backcab

Votre professeur a raison: les tests unitaires peuvent être en boîte noire ou en boîte blanche. La différence est moins sur ce que le testeur sait, mais plus sur la façon dont vous générez des cas de test.

Avec les tests de boîte noire, vous ne regardez que l'interface et (si elle existe) la spécification d'un composant. Lorsqu'une fonction a une signature int foo(int a, int b), je peux immédiatement générer quelques cas de test juste en testant des entiers intéressants: zéro, un, moins un, des nombres à plusieurs chiffres, INT_MAX, INT_MAX - 1 et ainsi de suite. Les tests de boîte noire sont excellents car ils sont indépendants de la mise en œuvre. Mais ils pourraient aussi manquer des cas importants.

Avec un test en boîte blanche, je regarde l'implémentation, c'est-à-dire le code source et génère des cas de test à partir de cela. Par exemple, je pourrais vouloir atteindre une couverture de chemin de 100% pour une fonction. Je choisis ensuite des valeurs d'entrée pour que tous les chemins soient empruntés. Les tests en boîte blanche sont excellents car ils peuvent exercer de manière exhaustive un morceau de code, avec beaucoup plus de confiance qu'un test en boîte noire. Mais ils pourraient ne tester que les détails de l'implémentation, pas un comportement réellement important. Dans certains cas, ils sont clairement une perte de temps.

Puisqu'un test en boîte blanche est dérivé de l'implémentation, il ne peut être écrit qu'après. Un test de boîte noire est dérivé de la conception/interface/spécification et peut donc être écrit avant ou après la mise en œuvre. TDD n'est ni clairement une boîte noire ni une boîte blanche. Étant donné que tout comportement est d'abord exprimé par un test, puis que le code minimal pour ce comportement est implémenté, TDD aboutit à des cas de test similaires à un test de boîte blanche. Mais quand on regarde le flux d'informations, les tests TDD ne sont pas dérivés du code source, mais d'exigences externes. Par conséquent, TDD ressemble plus à une boîte noire.

20
amon

Si vous entreprenez un développement piloté par les tests, alors en théorie tous vos tests unitaires devraient être en boîte noire. C'est votre "approche test-first". Vous écrivez le contrat (interface), écrivez les tests pour ce contrat, puis le contrat est rempli par l'implémentation. Le test ne sait donc rien et ne devrait rien savoir de la mise en œuvre.

Après tout, quand vous écrivez un test, que testez-vous? Méthodes/fonctions publiques.

Si vous deviez écrire l'interface pour une classe, puis écrire les tests, et ensuite vous êtes frappé par un bus, le gars qui écrit la classe pendant que vous êtes à l'hôpital devrait pouvoir le faire à partir de votre interface, non? Il ne devrait pas avoir à le jeter et à écrire sa propre interface et ses propres tests.

Lorsque cela se désagrège quelque peu, c'est quand vous devez vous moquer de quelque chose dont la mise en œuvre dépend, mais si vous vous trouvez dans la situation où vous vous moquez de quelque chose qui n'est jamais exposé publiquement, alors vous avez fait une erreur, et vous devez regardez Injection de dépendances et al . Par conséquent, je dirais que les tests unitaires en boîte blanche, et non le noir, devraient être l'exception.

Considérez 'Test sur les toilettes - Le comportement du test n'est pas implémenté' , dans lequel l'implémentation d'une classe est modifiée mais les tests doivent toujours être valides.

Cependant, si vous devez vous assurer que votre couverture de code est en place (c'est-à-dire que tous les chemins conditionnels sont testés dans l'implémentation), alors vous devrez absolument effectuer un test unitaire en boîte blanche, car la seule façon de savoir ce que votre chemins sont en regardant les chemins dans l'implémentation.

4
AdamJS

Je dirais que tous les tests unitaires bien écrits sont intrinsèquement "boîte noire". Bien sûr, je pourrais avoir une implémentation à l'esprit lorsque j'écris le test, mais cette implémentation peut changer lorsque je refactorise. Le test ne doit donc utiliser que des API publiques pendant le test afin de tester la fonctionnalité, pas l'implémentation. Il ne se soucie pas des détails de mise en œuvre, donc ses tests de boîte noire.

Si j'écris des tests qui accèdent aux aspects internes ou privés de l'unité testée, alors je teste les détails d'implémentation: je suis un test en boîte blanche. Mais j'écris également des tests fragiles qui peuvent facilement se casser lorsque l'implémentation est modifiée. Ces tests en boîte blanche sont donc une mauvaise idée et doivent être évités.

Conclusion: si vous testez la boîte blanche avec des tests unitaires, vous avez des tests mal construits. Seul test de boîte arrière avec ces tests unitaires. Votre professeur a raison: ça peut être l'un ou l'autre. Mais seulement si mal fait.

3
David Arno

J'étais en train d'écrire des tests unitaires qui effectuent des tests en boîte noire. Autrement dit, je teste les méthodes publiques dans une classe et par implication de la logique de test des résultats dans les méthodes privées qu'elles appellent.

Je le fais en changeant les entrées de la méthode publique en cours de test unitaire et en testant les sorties attendues qui sont déterminées ou modifiées par la logique dans les méthodes privées de support, dont la mise en œuvre, mes "tests unitaires" n'ont besoin de rien savoir.

Donc, rien ne vous empêche d'effectuer des tests de boîte noire sur les tests unitaires et les tests se briseront si quelqu'un gâche l'implémentation de la logique de support cachée. En fait, cela semble être une approche supérieure et plus efficace qu'une unité de boîte blanche testant tout dans une classe pour le plaisir. Je suis avec le professeur.

1
Shooresh