Mit dem Modul DocTest kann man sehr schnell und einfach kleine Codebeispiele in Docstrings testen. Am besten wird das ersichtlich durch ein kleines Beispiel:
Minimal Beispiel
1 def MeineFunktion(a, b):
2 """
3 Minimales DocTest Beispiel:
4
5 >>> MeineFunktion(1, 2)
6 3
7 >>> a = "Foo"
8 >>> b = "Bar"
9 >>> MeineFunktion(a, b)
10 'FooBar'
11 >>> MeineFunktion("text", 1234)
12 Traceback (most recent call last):
13 ...
14 TypeError: cannot concatenate 'str' and 'int' objects
15 """
16 c = a + b
17 return c
18
19 if __name__ == "__main__":
20 import doctest
21 doctest.testmod()
Beispiel mit Kommentaren
1 def MeineFunktion(a, b):
2 """
3 Das ist eine Sinnlose Funktion um einen DocTest durch ein einfaches
4 Beispiel zu beschreiben.
5
6 Ähnlich wie im interaktiven Python Interpreter kann man hier im Doc String
7 Tests einbauen. Mit ">>>" leitet man den Sourcecode ein, der ausgeführt
8 werden soll. In der Zeile danach, muß man das zu Erwartende Ergebnis
9 angeben. DocTest vergleicht das und liefert im Fehlerfall eine detailierte
10 Fehlermeldung.
11
12 Zu beachten ist, das nach dem DocTest eine Leerzeile zu den normalen
13 Kommentaren gemacht werden muß.
14
15 Ein Beispiel:
16
17 >>> MeineFunktion(1, 2) # Aufruf der Funktion mit Beispiel Parametern
18 3
19
20 3 ist das zu erwartende Ergebnis. Wenn was anderes rück geliefert wird,
21 wird eine detailierte DocTest Fehlermeldung zurück geliefert.
22
23
24 Hier ein Beispiel was falsch ist und ein Fehler liefert:
25
26 >>> MeineFunktion(1, 2)
27 'Absichtlich falsches Ergebnis.'
28
29
30 Es ist auch möglich mehrerere Zeilen Code auszuführen. z.B.:
31
32 >>> a = "Foo"
33 >>> b = "Bar"
34 >>> MeineFunktion(a, b)
35 'FooBar'
36
37
38 Man kann auch Exceptions abfragen. Hier ein Beispiel wo versucht wird ein
39 String und eine Zahl zu addieren, was natürlich ein TypeError verursacht.
40 Es wird also geprüft, ob wirklich ein TypeError ausgelöst wird. Der Test
41 ist also nicht bestanden, wenn *kein* TypeError geworfen wird.
42
43 >>> MeineFunktion("text", 1234)
44 Traceback (most recent call last):
45 ...
46 TypeError: cannot concatenate 'str' and 'int' objects
47 """
48 c = a + b
49 return c
50
51
52 if __name__ == "__main__":
53 import doctest
54 doctest.testmod()
Die Ausgabe sieht dann wie folgt aus:
**********************************************************************
File "test.py", line 28, in __main__.MeineFunktion
Failed example:
MeineFunktion(1, 2)
Expected:
'Absichtlich falsches Ergebnis.'
Got:
3
**********************************************************************
1 items had failures:
1 of 6 in __main__.MeineFunktion
***Test Failed*** 1 failures.
Tipps für das schreiben von Doc Tests
Erstellen von DocTests
Python Interpreter nutzten
Man kann natürlich den interaktiven Python Interpreter starten, das Modul importieren und dann mit der Funktion spielen. Danach kann man per Copy&Paste das ganze in den Doc String hinterlegen.
interaktiv ohne Interpreter
Wenn die Ergebnisse einer Funktion nicht direkt ersichtlich sind, kann man auch absichtlich falsche DocTest schreiben um aus den Fehlermeldungen die richtigen Ergebnisse per Copy&Paste übernehmen zu können. Also man nutzt einem Editor, mit dem man schnell und einfach die aktuelle Datei ausführen kann. Nun schreibt man einen DocTest mit einem extra falschen Ergebnis und startet das Skript. Aus der DocTest Fehlermeldung kann man dann das richtige Ergebnis ablesen.
Was gehört in DocTests?
DocTests in Docstrings sind weniger dazu gedacht den Code im Modul zu testen, sondern mehr dazu die Dokumentation zu testen. Nichts ist frustrierender als fremder Code mit Beispielen die nicht funktionieren. Man sollte also immer daran denken, dass man in den Docstring nicht alle möglichen Testfälle für eine Funktion unterbringt, sondern nur Beispiele die dem Leser der Dokumentation die Funktion verständlicher machen.
Das doctest Modul bietet aber auch die Möglichkeit beliebige Textdateien nach Tests zu durchsuchen und diese auszuführen. Auf diese Weise lassen sich nicht nur Beispiele in Tutorials testen, sondern man kann auch sehr einfach Textdateien mit Unittests anlegen.
Für das Format der Textdateien gilt das selbe wie für Docstrings: Die Tests müssen im Format des interaktiven Interpreters geschrieben sein und zwischen den Tests und umgebendem Text muss mindestens eine Leerzeile stehen.
Aufruf des Moduls als Programm
Seit Python 2.4 kann man das doctest-Modul mit der Option -m auch als Programm aufrufen. Angenommen in der Datei tutorial.txt sind Beispiele im Doctest-Format, so kann man diese so ausführen/testen lassen:
$ python -m doctest tutorial.txt