web-dev-qa-db-fra.com

Python - doctest vs unittest

J'essaie de commencer avec les tests unitaires dans Python et je me demandais si quelqu'un pouvait expliquer les avantages et les inconvénients de doctest et unittest.

Pour quelles conditions utiliseriez-vous chacun?

153
Sean

Les deux sont précieux. J'utilise à la fois doctest et nose prenant la place de unittest. J'utilise doctest pour les cas où le test donne un exemple d'utilisation réellement utile comme documentation. Généralement, je ne rend pas ces tests complets, visant uniquement à des fins informatives. J'utilise efficacement doctest à l'envers: non pas pour tester mon code est correct en fonction de mon doctorat, mais pour vérifier que ma documentation est correcte en fonction du code.

La raison en est que je trouve que les doctests complets encombrent beaucoup trop votre documentation, donc vous vous retrouverez soit avec des docstrings inutilisables, soit avec des tests incomplets.

Pour tester réellement le code , le but est de tester minutieusement chaque cas, plutôt que d'illustrer ce qui se fait par exemple, ce qui est un objectif différent qui je pense est mieux respecté par d'autres cadres.

166
Brian

J'utilise unittest presque exclusivement.

De temps en temps, je mettrai des trucs dans une docstring utilisable par le docteur.

95% des cas de test sont les plus instables.

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.

45
S.Lott

Un autre avantage du doctesting est que vous pouvez vous assurer que votre code fait ce que dit votre documentation. Après un certain temps, les modifications logicielles peuvent faire votre documentation et votre code faire des choses différentes. :-)

30
Jason Baker

Je travaille en tant que bioinformaticien, et la plupart du code que j'écris est 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 peut être exagéré, et les doctests sont un compromis utile. Ils sont plus rapides à écrire et puisqu'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 passer votre script à un chercheur qui n'est pas expert en programmation. Certaines personnes trouvent qu'il est très difficile de comprendre comment les unités de paiement sont structurées; d'autre part, 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 reprendre ma réponse: les doctests sont utiles lorsque vous devez écrire de petits scripts, et quand vous devez les passer ou les montrer à des chercheurs qui ne sont pas des informaticiens.

25
dalloliogm

Si vous venez de commencer avec l'idée de 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 milieu où vous avez utilisé JUnit ou quelque chose de similaire, où vous voulez pouvoir écrire des tests unitaires de la même manière que vous l'avez été ailleurs.

13
Greg Hewgill

L'utilisation des deux est une option valide et plutôt simple. Le module doctest fournit les méthodes DoctTestSuite et DocFileSuite qui créent une suite de tests compatible avec unittest à partir d'un module ou d'un fichier, respectivement.

J'utilise donc les deux et j'utilise typiquement 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 doctest aide documenter la fonction, plutôt que de la nuire.

Mais pour les cas plus compliqués et pour un ensemble plus complet de cas de test, j'utilise unittest qui offre plus de contrôle et de flexibilité.

7
davidavr

J'utilise exclusivement unittest; Je pense que Doctest encombre trop le module principal. Cela a probablement à voir avec la rédaction de tests approfondis.

7
Tony Arkles

Je n'utilise pas doctest en remplacement de 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 que j'obtiens de unittest. doctest résout le danger bien plus subtil d'avoir des commentaires obsolètes trompant la maintenance du code.

6
rahmu

Je n'utilise presque jamais de doctests. Je veux que mon code soit auto-documenté, et les docstrings fournissent la documentation à l'utilisateur. L'IMO qui ajoute 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.

4
JimB

Doctest peut parfois conduire à un mauvais résultat. 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 s'imprime comme un entier s'il s'agit d'un nombre entier. Supposons alors que vous ayez une fonction qui retourne rationnelle. Ainsi, un doctest ne différenciera pas si la sortie est un nombre entier rationnel ou un nombre entier.

3
Harsh

Je préfère les systèmes basés sur la découverte ("nose" et "py.test", en utilisant le premier actuellement).

doctest est sympa quand le test est aussi bon comme documentation, sinon ils ont trop tendance à encombrer le code.

2
lazy1