Réponses:
Les deux sont précieux. J'utilise à la fois doctest et nose pour remplacer unittest. J'utilise doctest pour les cas où le test donne un exemple d'utilisation qui est réellement utile comme documentation. En général, je ne fais pas ces tests exhaustifs, dans un but uniquement informatif. J'utilise effectivement doctest à l'envers: non pas pour tester que mon code est correct en fonction de mon doctest, mais pour vérifier que ma documentation est correcte en fonction du code.
La raison est que je trouve que les doctests complets encombreront beaucoup trop votre documentation, donc vous vous retrouverez soit avec des docstrings inutilisables, soit avec des tests incomplets.
Pour tester réellement le code , l'objectif est de tester minutieusement chaque cas, plutôt que d'illustrer ce qui est fait par exemple, ce qui est un objectif différent qui, je pense, est mieux rempli par d'autres frameworks.
J'utilise unittest presque exclusivement.
De temps en temps, je mettrai des trucs dans une docstring utilisable par doctest.
95% des cas de test sont unittest.
Pourquoi? J'aime garder les docstrings un peu plus courts et plus précis. Parfois, les cas de test aident à clarifier une docstring. La plupart du temps, les cas de test de l'application sont trop longs pour une docstring.
docstring
et quoi non. En fait, j'aime docstring dans les termes qui montre explicitement comment utiliser une interface, mais l'utiliser à la fois pour cela et pour les tests unitaires peut ne pas convenir.
Un autre avantage du doctesting est que vous pouvez vous assurer que votre code fait ce que votre documentation dit. Après un certain temps, les modifications apportées au logiciel peuvent amener votre documentation et votre code à faire des choses différentes. :-)
Je travaille comme bioinformaticien, et la plupart du code que j'écris sont des scripts "une fois, une tâche", du code qui ne sera exécuté qu'une ou deux fois et qui exécutera une seule tâche spécifique.
Dans cette situation, écrire de gros tests unitaires peut être exagéré, et les doctests sont un compromis utile. Ils sont plus rapides à écrire, et comme ils sont généralement incorporés dans le code, ils permettent de toujours garder un œil sur le comportement du code, sans avoir à ouvrir un autre fichier. C'est utile lors de l'écriture de petits scripts.
De plus, les doctests sont utiles lorsque vous devez transmettre votre script à un chercheur qui n'est pas expert en programmation. Certaines personnes trouvent très difficile de comprendre comment les unités unitaires sont structurées; d'un autre côté, les doctests sont de simples exemples d'utilisation, donc les gens peuvent simplement les copier et les coller pour voir comment les utiliser.
Donc, pour résumer ma réponse: les doctests sont utiles lorsque vous devez écrire de petits scripts, et lorsque vous devez les transmettre ou les montrer à des chercheurs qui ne sont pas des informaticiens.
Si vous ne faites que commencer avec l'idée des tests unitaires, je commencerais par doctest
parce qu'il est si simple à utiliser. Il fournit également naturellement un certain niveau de documentation. Et pour des tests plus complets avec doctest
, vous pouvez placer des tests dans un fichier externe afin qu'il n'encombre pas votre documentation.
Je suggérerais unittest
si vous venez d'un passé ayant utilisé JUnit ou quelque chose de similaire, où vous voulez être en mesure d'écrire des tests unitaires de la même manière que vous l'avez été ailleurs.
doctest
pour commencer), mais je l'ai finalement regretté. Pour les cas de test non triviaux, j'ai perdu la coloration syntaxique et l'auto-complétion de mon éditeur. Lorsque les tests étaient dans un fichier séparé, je ne pouvais plus l'exécuter directement à partir de l'éditeur - je devais changer le contexte pour revenir au fichier source correspondant à chaque fois.
J'utilise exclusivement unittest; Je pense que doctest encombre trop le module principal. Cela a probablement à voir avec la rédaction de tests approfondis.
Utiliser les deux est une option valable et plutôt simple. Le doctest
module fournit les méthodes DoctTestSuite
et DocFileSuite
qui créent respectivement une suite de tests compatible unittest à partir d'un module ou d'un fichier.
J'utilise donc les deux et j'utilise généralement doctest pour des tests simples avec des fonctions qui nécessitent peu ou pas de configuration (types simples pour les arguments). En fait, je pense que quelques tests de doctrine aident à documenter la fonction, plutôt que de la nuire.
Mais pour les cas plus complexes, et pour un ensemble plus complet de cas de test, j'utilise unittest qui offre plus de contrôle et de flexibilité.
Je n'utilise pas doctest pour remplacer unittest. Bien qu'ils se chevauchent un peu, les deux modules n'ont pas la même fonction:
J'utilise unittest
comme cadre de test unitaire, ce qui signifie qu'il m'aide à déterminer rapidement l'impact de toute modification sur le reste du code.
J'utilise doctest
comme garantie que les commentaires (à savoir les docstrings) sont toujours pertinents pour la version actuelle du code.
Les avantages largement documentés du développement piloté par les tests dont je bénéficie unittest
. doctest
résout le danger beaucoup plus subtil d'avoir des commentaires obsolètes trompant la maintenance du code.
Je n'utilise presque jamais de doctests. Je veux que mon code soit auto-documenté et que les docstrings fournissent la documentation à l'utilisateur. L'OMI ajoutant des centaines de lignes de tests à un module rend les docstrings beaucoup moins lisibles. Je trouve également que les tests unitaires sont plus faciles à modifier en cas de besoin.
Doctest
peut parfois conduire à de mauvais résultats. Surtout lorsque la sortie contient des séquences d'échappement. Par exemple
def convert():
"""
>>> convert()
'\xe0\xa4\x95'
"""
a = '\xe0\xa4\x95'
return a
import doctest
doctest.testmod()
donne
**********************************************************************
File "hindi.py", line 3, in __main__.convert
Failed example:
convert()
Expected:
'क'
Got:
'\xe0\xa4\x95'
**********************************************************************
1 items had failures:
1 of 1 in __main__.convert
***Test Failed*** 1 failures.
Ne vérifie pas non plus le type de sortie. Il compare simplement les chaînes de sortie. Par exemple, il a rendu un type rationnel qui imprime exactement comme un entier s'il s'agit d'un nombre entier. Supposons alors que vous ayez une fonction qui renvoie rationnelle. Ainsi, un doctest ne différenciera pas si la sortie est un nombre entier rationnel ou un nombre entier.
r""" ... """
) pour résoudre le premier problème.
'\\xe0\\xa4\\x95'
dans votre docstring.
Je préfère les systèmes basés sur la découverte ("nose" et "py.test", en utilisant le premier actuellement).
doctest est bien quand le test est aussi bon comme documentation, sinon ils ont tendance à trop encombrer le code.