Python - doctest vs unittest [fermé]

160

J'essaye de me lancer dans les tests unitaires en 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?

Sean
la source

Réponses:

178

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.

Brian
la source
29
Il y a beaucoup moins de passe-partout, et je trouve les tests beaucoup plus simples à écrire (et à lire). Le faible coût de démarrage pour écrire des tests (c'est-à-dire simplement écrire une fonction "test_foo ()" et aller) aide également à combattre la tentation de faire les bits de code intéressants avant de clouer vos tests.
Brian
6
Je pense que c'est une réponse fantastique.
James Brady
Quels autres frameworks de test utilisez-vous? Ou est-ce exclusivement du nez?
Joe le
6
Compte tenu de l'âge de cette réponse, il vaut probablement la peine de mentionner qu'une grande partie du «passe-partout» des anciennes versions d'unittest a largement disparu. J'aime toujours mieux Nose aussi, mais c'est plutôt un jeu d'enfant.
Adam Parkin
1
FYI nose est en "mode maintenance" depuis plusieurs années et cessera probablement tout développement (en l'absence d'intervention tierce). Ses responsables recommandent aux nouveaux projets d'utiliser une alternative.
Six
48

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.

S.Lott
la source
Ce serait cool de voir un exemple, ce que vous pensez est approprié docstringet 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.
user1767754
33

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. :-)

Jason Baker
la source
6
+1 de moi - excellent point
doug
28

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.

dalloliogm
la source
6
"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." Excellent point. Je fais la même chose et les programmeurs non python sont toujours étonnés que la documentation puisse être exécutée.
Daniel Canas du
14

Si vous ne faites que commencer avec l'idée des tests unitaires, je commencerais par doctestparce 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 unittestsi 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.

Greg Hewgill
la source
4
J'ai été encouragé dans cette direction ( doctestpour 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.
Oddthinking
7

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

Tony Arkles
la source
7

Utiliser les deux est une option valable et plutôt simple. Le doctestmodule fournit les méthodes DoctTestSuiteet DocFileSuitequi 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é.

Davidavr
la source
7

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 unittestcomme 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 doctestcomme 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. doctestrésout le danger beaucoup plus subtil d'avoir des commentaires obsolètes trompant la maintenance du code.

rahmu
la source
4

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.

JimB
la source
4

Doctestpeut 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.

Dur
la source
5
Vous pouvez utiliser des docstrings bruts ( r""" ... """) pour résoudre le premier problème.
icktoofay
Fonctionne très bien dans Python 3.4. Pour le faire fonctionner également dans Python 2.7, utilisez '\\xe0\\xa4\\x95'dans votre docstring.
Cees Timmerman
J'ai également constaté que les littéraux Unicode ne fonctionnent pas non plus avec les doctests (même avec la bonne ligne de commentaire 'coding utf-8' en haut du fichier. Généralement les doctests ne sont pas aussi bien supportés que les tests unittest, donc il y a quelques bugs qui ne sont pas corrigés.
RichVel
2

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.

paresseux1
la source
le nez semble incroyablement utile; Je n'ai pas encore eu la chance de l'utiliser, mais j'ai de grands espoirs :)
Tony Arkles
nose est à peu près le framework de test le plus simple à utiliser, IMO. Cela permet d'écrire et d'exécuter des cas de test sans effort.
Kamil Kisiel