Les tests unitaires sont-ils vraiment utilisés comme documentation?


22

Je ne peux pas compter le nombre de fois que j'ai lu des déclarations dans la veine des «tests unitaires sont une source très importante de documentation du code testé». Je ne nie pas qu'elles soient vraies.

Mais personnellement, je ne me suis jamais retrouvé à les utiliser comme documentation. Pour les frameworks typiques que j'utilise, les déclarations de méthode documentent leur comportement et c'est tout ce dont j'ai besoin. Et je suppose que les tests unitaires sauvegardent tout ce qui est indiqué dans cette documentation, ainsi que probablement d'autres éléments internes, donc d'un côté, il duplique la ducumentation tandis que de l'autre, il pourrait en ajouter d'autres qui ne sont pas pertinents.

La question est donc: quand les tests unitaires sont-ils utilisés comme documentation? Quand les commentaires ne couvrent pas tout? Par des développeurs qui étendent la source? Et que révèlent-ils qui peuvent être utiles et pertinents que la documentation elle-même ne peut pas exposer?


4
Je n'ai jamais pensé à utiliser directement le test unitaire comme documentation. Je pense que les tests unitaires sont souvent illisibles, car de nombreux développeurs ne prennent pas le temps de les écrire clairement.
superM

10
Les commentaires peuvent être faux.

2
Je sais que vous posez des questions spécifiques sur les tests unitaires, mais je noterais également que les tests d'intégration / système sont également une documentation vraiment utile, juste à un niveau différent
jk.

3
J'ai vu des tests unitaires qui seraient mieux caractérisés comme des «expériences unitaires». Leur dépendance vis-à-vis de facteurs externes était au point de les rendre presque inutiles. Ils étaient également très peu clairs. (Oui, j'ai un objectif à long terme pour les refaçonner pour qu'ils soient meilleurs, mais je fais aussi d'autres choses…)
Donal Fellows

4
Les tests unitaires @Ant invoquent le code réel et documentent la réponse attendue et la comparent à la réponse réelle. Que le code invoqué soit correct ou non, ce n'est pas la question - les tests documentent comment l'invoquer.

Réponses:


17

Ce n'est PAS une documentation de référence ABSOLUE

Notez que la plupart des éléments suivants s'appliquent également aux commentaires, car ils peuvent se désynchroniser avec le code, comme les tests (bien qu'il soit moins exécutoire).

Donc, au final, la meilleure façon de comprendre le code est d'avoir un code de travail lisible .

Dans la mesure du possible et sans écrire des sections de code de bas niveau câblées ou des conditions particulièrement délicates, une documentation supplémentaire sera cruciale.

  • Les tests peuvent être incomplets:
    • L'API a changé et n'a pas été testée,
    • La personne qui a écrit le code a écrit les tests pour les méthodes les plus faciles à tester en premier au lieu des méthodes les plus importantes à tester, puis n'a pas eu le temps de terminer.
  • Les tests peuvent être obsolètes.
  • Les tests peuvent être court-circuités de manière non évidente et ne pas être réellement exécutés.

MAIS ils sont TOUJOURS un complément de documentation UTILE

Cependant, en cas de doute sur ce que fait une classe particulière, surtout si elle est plutôt longue, obscure et manquant de commentaires (vous connaissez le genre ...), j'essaie rapidement de trouver sa ou ses classes de test et de vérifier:

  • ce qu'ils essaient de vérifier (donne un indice sur les informations les plus importantes, sauf si le développeur a fait l'erreur mentionnée ci-dessus en ne mettant en œuvre que les tests "faciles"),
  • et s'il y a des cas d'angle.

De plus, s'ils sont écrits en utilisant un style BDD , ils donnent une assez bonne définition du contrat de la classe . Ouvrez votre IDE (ou utilisez grep) pour ne voir que les noms de méthode et tada: vous avez une liste de comportements.

Les régressions et les bogues ont également besoin de tests

Aussi, c'est une bonne pratique d'écrire des tests de régression et des rapports de bogues: vous corrigez quelque chose, vous écrivez un test pour reproduire le cas. En y repensant, c'est un bon moyen de trouver le rapport de bogue pertinent et tous les détails sur un ancien problème, par exemple.

Je dirais qu'ils constituent un bon complément à une véritable documentation et au moins une ressource précieuse à cet égard. C'est un bon outil, s'il est utilisé correctement. Si vous commencez à tester tôt dans votre projet et que vous en faites une habitude, cela POURRAIT être une très bonne documentation de référence. Sur un projet existant avec de mauvaises habitudes de codage qui empestent déjà la base de code, manipulez-les avec soin.


Puis-je demander pourquoi j'ai été rétrogradé? Qu'est-ce qui vous coince là-dedans ou avec quoi êtes-vous en désaccord?
haylem

2
La meilleure partie (IMO) de votre argument est écrite dans la plus petite police - la meilleure façon de comprendre le code est d'avoir un code lisible en premier lieu. Je changerais cela en "code lisible et fonctionnel", mais je suis d'accord. Ensuite, si vous regardez à nouveau les tests unitaires - les tests en cours fonctionnent comme du code (et comme tout le code, devraient être lisibles), donc c'est en fait une documentation assez bonne (si souvent trop locale) lorsqu'elle est bien faite.
Joris Timmermans

@MadKeithV: merci. J'ai mis à jour pour "code lisible et fonctionnel" et poussé un peu plus haut.
haylem

11

Une interprétation est que les tests unitaires sont de la "documentation exécutable". Vous pouvez exécuter les tests unitaires par rapport au code et il vous dira s'il fonctionne toujours tel qu'il était lorsque les tests ont été écrits pour réussir ou non. De cette manière, les tests unitaires "documentent" la fonctionnalité du système à un moment donné, de manière exécutable.

D'un autre côté, j'ai aussi rarement lu le code de test unitaire en tant que "documentation" pour comprendre la fonctionnalité. Un test unitaire unique est trop localisé, spécifique et abstrait de manière à pouvoir vous en dire beaucoup sur le système réel qui se cache derrière la classe testée.


5

Si par la documentation vous voulez dire que je veux quelque chose pour savoir comment fonctionne le code , les tests unitaires sont de parfaits petits exemples du fonctionnement des unités du code dans les cas attendus , les cas marginaux et les erreurs (aka bugs ). De plus, vos tests pourraient être créés avant que le code ne soit écrit, ce qui sous-tend ce que le code devrait faire d'un point de vue métier / exigence.

Remplacent-ils la documentation? Non.

Sont-ils un complément utile à la documentation? Oui.


4

Je vois les tests unitaires comme:

  • un moyen de prouver que la documentation est correcte (en supposant que la documentation correspond à l'implémentation de l'API).
  • un moyen de montrer à un développeur comment utiliser une fonctionnalité particulière; Les montages de tests unitaires / tests unitaires eux-mêmes sont généralement suffisamment petits pour que l'on puisse en tirer rapidement des enseignements.
  • et évidemment pour repérer tout bug de régression.

Dans une certaine mesure, ils peuvent être vus comme un complément à une documentation existante mais pas comme la documentation.


3

Je vais répondre à votre question en vous en posant une autre.

À quelle fréquence lorsque vous travaillez avec une nouvelle API / routine avez-vous lancé de l'aide pour rechercher un exemple de code de la chose que vous essayez d'utiliser? A défaut de basculer sur google pour une recherche en ligne d'exemples de code?

C'est exactement à ce moment que vous utiliseriez des tests unitaires comme documentation.

  • En fait, les tests unitaires peuvent être un peu plus rigoureux que les exemples de code normaux, car vous devriez avoir plusieurs tests (exemples).
  • Espérons que vos tests unitaires illustrent une bonne utilisation. Par exemple, ils montrent clairement toutes les dépendances essentielles via des objets normaux ou des objets fictifs. (Sinon, ce ne sont pas des tests unitaires particulièrement bons.)
  • REMARQUE: si vos commentaires ou votre "documentation normale" fournissent des exemples de code, vous violez en fait les principes DRY. Et ces exemples de code peuvent facilement devenir incorrects au fil du temps, alors qu'il y a beaucoup moins de chances de cela avec des tests unitaires régulièrement exécutés.
  • Si les tests unitaires sont approfondis (généralement un gros si ), ils doivent fournir des informations supplémentaires:
    • Tous les cas de bord connus clairement illustrés.
    • Toutes les exceptions attendues qui peuvent être levées.
    • Tous les bogues trouvés précédemment (cela est probablement plus utile lors de l'extension de l'unité testée que lors de l'écriture d'un nouveau client pour l'unité).
    • Toutes les règles commerciales sous-jacentes associées à l'unité. (si seulement)

Je soupçonne qu'il y a plusieurs raisons pour lesquelles le test unitaire n'a pas tendance à être utilisé comme documentation, même s'il pourrait être un excellent complément à une documentation plus traditionnelle:

  • Je me risquerais à suggérer que, souvent, les tests eux-mêmes ne sont pas suffisamment bien écrits à cet effet. D'autres réponses ont déjà fait allusion à des tests qui sont:
    • Incomplet.
    • Déroutant. (J'ai vu des cas de test qui n'appellent pas directement la méthode sous test - vous allez aux 3/4 niveaux profondément dans la pile d'appels avant qu'elle ne soit appelée et les conditions préalables à l'appel de la méthode sont dispersées à différents endroits dans une hiérarchie de classes complexe. )
    • Dépassé. (généralement, les tests doivent échouer lorsqu'ils deviennent obsolètes, mais ce n'est pas toujours le cas).
  • Il existe généralement de nombreux exemples d'utilisation déjà disponibles dans le code de production chaque fois que le besoin d'un exemple se fait sentir.
  • L'unité testée est si bien écrite (auto-documentée) que les méthodes n'ont pas besoin d'exemples. Je souhaite que!
  • D'après mon expérience en tant que programmeur, nous avons tendance à être très enthousiastes à l'idée de sauter au plus profond et de RTFM mardi prochain ...
  • Documentation et commentaires qui violent le principe DRY.

2

Les tests TL; DR Unit et les commentaires API sont complémentaires - certaines choses sont mieux décrites dans le code, et d'autres dans la prose.

Les tests unitaires sont principalement utiles pour documenter des cas spéciaux et des conditions de bord difficiles (et encombrants) à décrire dans les commentaires de l'API. De plus, les commentaires de l'API sont généralement destinés aux personnes qui souhaitent utiliser l'API.

Si vous souhaitez modifier le code, il y a généralement beaucoup plus que vous devez savoir, et certaines d'entre elles sont difficiles à mettre dans les commentaires (et ces commentaires deviennent obsolètes rapidement). Dans ce cas, un test unitaire sert également de documentation.

Un exemple: vous avez une méthode m (a, b)qui effectue un certain calcul. En raison des exigences de compatibilité descendante, il doit utiliser les entrées de cas spécial de a=0et a=-1, mais uniquement si best NULL. Mettre cela dans un commentaire est compliqué, détaillé et susceptible de devenir obsolète si l'exigence est supprimée ultérieurement.

Si vous effectuez des tests unitaires qui vérifient le comportement de m(0, NULL), m(-1, x)vous obtenez plusieurs avantages:

  • La description du comportement correct est claire, les malentendus sont réduits
  • Les gens ne peuvent pas ignorer l'exigence lorsqu'ils changent le code, contrairement à un commentaire

mais pour votre exemple, si ce comportement n'est pas du tout documenté dans le commentaire, un utilisateur peut obtenir des résultats inattendus pour ce cas de bord. Ce qui n'est pas exactement une bonne chose.
stijn

@stijn: Vrai. Dans ce cas, le meilleur moyen serait probablement d'avoir une brève mention du cas spécial dans les documents, ainsi que les tests unitaires pour les détails en désordre.
sleske
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.