Python - doctest vs. unittest [geschlossen]

159

Ich versuche, mit Unit-Tests in Python zu beginnen, und habe mich gefragt, ob jemand die Vor- und Nachteile von doctest und unittest erklären kann.

Für welche Bedingungen würden Sie jeweils verwenden?

Sean
quelle

Antworten:

177

Beides ist wertvoll. Ich benutze sowohl Doctest als auch Nase anstelle von Unittest. Ich verwende doctest für Fälle, in denen der Test ein Anwendungsbeispiel liefert, das tatsächlich als Dokumentation nützlich ist. Im Allgemeinen mache ich diese Tests nicht umfassend, sondern nur zur Information. Ich verwende doctest effektiv in umgekehrter Reihenfolge: Nicht um zu testen, ob mein Code basierend auf meinem doctest korrekt ist, sondern um zu überprüfen, ob meine Dokumentation basierend auf dem Code korrekt ist.

Der Grund dafür ist, dass ich finde, dass umfassende Doktrinen Ihre Dokumentation viel zu sehr überladen, sodass Sie entweder unbrauchbare Dokumentzeichenfolgen oder unvollständige Tests erhalten.

Um den Code tatsächlich zu testen , besteht das Ziel darin, jeden Fall gründlich zu testen, anstatt zu veranschaulichen, was anhand eines Beispiels geschieht. Dies ist ein anderes Ziel, das meiner Meinung nach von anderen Frameworks besser erreicht wird.

Brian
quelle
29
Es gibt viel weniger Boilerplate und ich finde Tests viel einfacher zu schreiben (und zu lesen). Die geringen Startkosten für das Schreiben von Tests (dh einfach eine "test_foo ()" - Funktion schreiben und loslegen) tragen auch dazu bei, die Versuchung zu bekämpfen, die interessanten Codebits auszuführen, bevor Sie Ihre Tests festnageln.
Brian
6
Ich denke, das ist eine fantastische Antwort.
James Brady
Welche anderen Test-Frameworks verwenden Sie? Oder ist es ausschließlich Nase?
Joe
6
Angesichts des Alters dieser Antwort ist es wahrscheinlich erwähnenswert, dass ein Großteil der "Boilerplate" älterer Versionen von unittest weitgehend verschwunden ist. Ich mag Nose auch immer noch besser, aber es ist so ziemlich ein Fehler.
Adam Parkin
1
Die FYI-Nase befindet sich seit einigen Jahren im "Wartungsmodus" und wird wahrscheinlich die gesamte Entwicklung einstellen (ohne Intervention von Drittanbietern). Die Betreuer empfehlen neuen Projekten, eine Alternative zu verwenden.
Sechs
48

Ich benutze fast ausschließlich unittest.

Hin und wieder werde ich ein paar Sachen in einen Docstring stecken, der von doctest verwendet werden kann.

95% der Testfälle sind unittest.

Warum? Ich mag es, Docstrings etwas kürzer und auf den Punkt zu bringen. Manchmal helfen Testfälle bei der Klärung eines Dokumentstrings. Meistens sind die Testfälle der Anwendung zu lang für eine Dokumentzeichenfolge.

S.Lott
quelle
Es wäre cool, ein Beispiel zu sehen, wofür Sie Ihrer Meinung nach geeignet sind docstringund was nicht. Eigentlich mag ich docstring in Begriffen, die explizit zeigen, wie man eine Schnittstelle verwendet, aber sowohl für diese als auch für Unit-Tests zu verwenden, passt möglicherweise nicht gut.
user1767754
33

Ein weiterer Vorteil von Doctesting besteht darin, dass Sie sicherstellen müssen, dass Ihr Code das tut, was Ihre Dokumentation vorschreibt. Nach einer Weile können Softwareänderungen dazu führen, dass Ihre Dokumentation und Ihr Code verschiedene Aufgaben ausführen. :-)

Jason Baker
quelle
6
+1 von mir - ausgezeichneter Punkt
Doug
28

Ich arbeite als Bioinformatiker und der größte Teil des Codes, den ich schreibe, besteht aus Skripten "einmalig, eine Aufgabe", Code, der nur ein- oder zweimal ausgeführt wird und eine einzelne bestimmte Aufgabe ausführt.

In dieser Situation kann das Schreiben großer Unittests übertrieben sein, und Doktests sind ein nützlicher Kompromiss. Sie sind schneller zu schreiben und da sie normalerweise im Code enthalten sind, können Sie immer im Auge behalten, wie sich der Code verhalten soll, ohne dass eine andere Datei geöffnet sein muss. Das ist nützlich, wenn Sie ein kleines Skript schreiben.

Doctests sind auch nützlich, wenn Sie Ihr Skript an einen Forscher weitergeben müssen, der kein Programmierexperte ist. Einige Leute finden es sehr schwierig zu verstehen, wie Unittests strukturiert sind; Auf der anderen Seite sind Doktrinen einfache Beispiele für die Verwendung, sodass die Benutzer sie einfach kopieren und einfügen können, um zu sehen, wie sie verwendet werden.

Um meine Antwort wieder aufzunehmen: Doktrinen sind nützlich, wenn Sie kleine Skripte schreiben müssen und wenn Sie sie weitergeben oder Forschern zeigen müssen, die keine Informatiker sind.

dalloliogm
quelle
6
"Doktrinen sind nützlich, wenn Sie kleine Skripte schreiben müssen und wenn Sie sie weitergeben oder Forschern zeigen müssen, die keine Informatiker sind." Hervorragender Punkt. Ich mache das Gleiche und die Nicht-Python-Programmierer sind immer wieder erstaunt, dass die Dokumentation ausgeführt werden kann.
Daniel Canas
14

Wenn Sie gerade erst mit der Idee des Unit-Tests beginnen, würde ich damit beginnen, doctestweil es so einfach zu bedienen ist. Es bietet natürlich auch ein gewisses Maß an Dokumentation. Und für umfassendere Tests mit doctestkönnen Sie Tests in einer externen Datei ablegen, damit Ihre Dokumentation nicht überladen wird.

Ich würde vorschlagen, unittestwenn Sie aus einem Umfeld stammen, in dem Sie JUnit oder ähnliches verwendet haben und in dem Sie Unit-Tests im Allgemeinen genauso schreiben möchten, wie Sie es anderswo getan haben.

Greg Hewgill
quelle
4
Ich wurde ( doctestzunächst) in diese Richtung ermutigt , bereute es aber schließlich. Bei nicht trivialen Testfällen habe ich die Syntaxhervorhebung und die automatische Vervollständigung meines Editors verloren. Wenn sich die Tests in einer separaten Datei befanden, konnte ich sie nicht mehr direkt vom Editor ausführen. Ich musste den Kontext jedes Mal wieder in die entsprechende Quelldatei ändern.
Oddthinking
7

Ich benutze ausschließlich unittest; Ich denke, dass doctest das Hauptmodul zu sehr durcheinander bringt. Dies hat wahrscheinlich mit dem Schreiben gründlicher Tests zu tun.

Tony Arkles
quelle
7

Die Verwendung von beiden ist eine gültige und recht einfache Option. Das doctestModul bietet die DoctTestSuiteund DocFileSuiteMethoden, mit denen aus einem Modul bzw. einer Datei eine unittest-kompatible Testsuite erstellt wird.

Daher verwende ich beide und verwende doctest normalerweise für einfache Tests mit Funktionen, die wenig oder gar kein Setup erfordern (einfache Typen für Argumente). Ich denke tatsächlich, dass ein paar Testtests helfen , die Funktion zu dokumentieren, anstatt sie zu beeinträchtigen.

Aber für kompliziertere Fälle und für eine umfassendere Reihe von Testfällen verwende ich unittest, das mehr Kontrolle und Flexibilität bietet.

davidavr
quelle
7

Ich benutze doctest nicht als Ersatz für unittest. Obwohl sie sich etwas überlappen, haben die beiden Module nicht die gleiche Funktion:

  • Ich verwende es unittestals Unit-Testing-Framework, was mir hilft, die Auswirkungen von Änderungen auf den Rest des Codes schnell zu bestimmen.

  • Ich verwende doctestals Garantie, dass Kommentare (nämlich Dokumentzeichenfolgen) für die aktuelle Version des Codes immer noch relevant sind.

Die weithin dokumentierten Vorteile der testgetriebenen Entwicklung, von denen ich profitiere unittest. doctestlöst die weitaus subtilere Gefahr, dass veraltete Kommentare die Pflege des Codes irreführen.

Rahmu
quelle
4

Ich benutze fast nie Doktests. Ich möchte, dass mein Code sich selbst dokumentiert, und die Dokumentzeichenfolgen stellen dem Benutzer die Dokumentation zur Verfügung. Wenn IMO einem Modul Hunderte von Testzeilen hinzufügt, sind die Dokumentzeichenfolgen weitaus weniger lesbar. Ich finde auch, dass Unit-Tests bei Bedarf einfacher zu ändern sind.

JimB
quelle
4

Doctestkann manchmal zu falschen Ergebnissen führen. Besonders wenn die Ausgabe Escape-Sequenzen enthält. Beispielsweise

def convert():
    """
    >>> convert()
    '\xe0\xa4\x95'
    """
    a = '\xe0\xa4\x95'
    return a
import doctest
doctest.testmod()

gibt

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

Überprüft auch nicht den Typ der Ausgabe. Es werden nur die Ausgabezeichenfolgen verglichen. Zum Beispiel hat es einen Typ rational gemacht, der genau wie eine ganze Zahl druckt, wenn es sich um eine ganze Zahl handelt. Nehmen wir dann an, Sie haben eine Funktion, die rational zurückgibt. Ein Doctest unterscheidet also nicht, ob es sich bei der Ausgabe um eine rationale Ganzzahl oder eine Ganzzahl handelt.

Hart
quelle
5
Sie können raw docstrings ( r""" ... """) verwenden, um das erste Problem zu beheben.
icktoofay
Funktioniert gut in Python 3.4. Verwenden Sie '\\xe0\\xa4\\x95'in Ihrem Dokumentstring, damit es auch in Python 2.7 funktioniert.
Cees Timmerman
Ich habe auch festgestellt, dass Unicode-Literale auch nicht mit Doctests funktionieren (selbst mit der richtigen 'Coding Utf-8'-Kommentarzeile oben in der Datei. Im Allgemeinen werden Doctests nicht so gut unterstützt wie unittest-Tests, daher gibt es einige Fehler das wird nicht behoben.
RichVel
2

Ich bevorzuge die entdeckungsbasierten Systeme ("Nase" und "py.test", wobei die ersteren derzeit verwendet werden).

doctest ist nett, wenn der Test auch als Dokumentation gut ist, sonst neigen sie dazu, den Code zu sehr zu überladen.

faul1
quelle
Nase sieht unglaublich nützlich aus; Ich habe noch keine Chance bekommen, es zu benutzen, aber ich habe große Hoffnungen :)
Tony Arkles
Nase ist so ziemlich das am einfachsten zu verwendende Test-Framework, IMO. Es macht das Schreiben und Ausführen von Testfällen ziemlich mühelos.
Kamil Kisiel