Kapitel 25
Testen und Tuning
684
Nun liefert die direkte Ausführung des Skripts den folgenden Testbericht. Er ist weniger
ausführlich (die Option
verbose hat den voreingestellten Wert False) und geht nur noch
auf Fehler ein.
25.3 Praxisbeispiel: Suche nach dem Wort des Jahres
Weitere Techniken zum Testen mit doctest erläutere ich nun an einem etwas komplexeren
objektorientierten Programm. Es handelt sich um ein Online-System, das aus einer stati-
schen HTML-Seite mit Formular und zwei Python-Skripten (eines davon ist ein CGI-Skript)
besteht.
Auf einer interaktiven HTML-Seite können Besucher einen Vorschlag für das »Wort des Jah-
res« machen (Abbildung 25.1). In Deutschland veröffentlicht die Gesellschaft für deutsche
Sprache (Wiesbaden) seit 1972 jedes Jahr eine Liste mit »Wörtern des Jahres«, die die öffent-
liche Diskussion des jeweiligen Jahres besonders gut charakterisieren (
http://www.gfds.
de/
).
" " "
summe = 0
for n in s:
summe = summe + n**2
return summe
if __name__ == "__main__":
import doctest
doctest.testmod()
********************************************************
File "... __main__", line 10, in __main__.quadratsumme
Failed example:
quadratsumme ()
Exception raised:
Traceback (most recent call last):
File "C:\Python35\lib\doctest.py", line 1321, in __run
compileflags, 1) in test.globs
File "<doctest __main__.quadratsumme[3]>", line 1, in ?
quadratsumme ()
TypeError: quadratsumme() takes exactly 1 argument (0 given)
********************************************************
1 items had failures:
1 of 4 in __main__.quadratsumme
***Test Failed*** 1 failures.
>>>
685
25.3
Praxisbeispiel: Suche nach dem Wort des Jahres
Zurück zu unserem Beispielprogramm. Sobald ein Besucher die Schaltfläche Abschicken
anklickt, wird das CGI-Skript aufgerufen, das den Vorschlag verarbeitet. Zurückgeschickt
wird eine Antwort wie in Abbildung 25.2. Sie enthält die fünf bisher am häufigsten vorge-
schlagenen Wörter und den Rangplatz des Wortes, das der Besucher eingegeben hat.
Abb. 25.1: Statische Webseite mit Eingabemöglichkeit
Abb. 25.2: Dynamisch generierte Antwort des CGI-Skripts
Statische Webseite mit Formular
Der folgende HTML-Text definiert die statische Webseite aus Abbildung 25.1. Wenn Sie es
ausprobieren wollen, starten Sie den HTTP-Server
httpd.py im Ordner ...python/http-
server
und besuchen dann mit Ihrem Browser den URL http://localhost:8000/html/.
Kapitel 25
Testen und Tuning
686
Beim Klick auf den SUBMIT-Button wird das Skript mit dem URL http://localhost:
8000/cgi-bin/wdj.py
aufgerufen. Falls der Besucher der Seite in das Eingabefeld das
Wort Schnupfen eingegeben hat, wird dem URL folgender Querystring angehängt:
Klassenstruktur
Das Python-Programm besteht im Wesentlichen aus zwei Klassen, die in zwei separaten
Modulen definiert sind. Sie sind im
cgi-bin-Verzeichnis des HTTP-Servers gespeichert.
Das Skript wdj.py ist das eigentliche CGI-Skript, das von der statischen Webseite aus
aufgerufen wird. Es enthält die Klasse
Responder, die für die Kommunikation mit dem
Client zuständig ist. Ein Objekt dieser Klasse verarbeitet die im Querystring übergebene
Variable und gibt mit einer
print()-Anweisung ein HTTP-Paket an den Client zurück.
Das Modul ranking.py enthält die Klasse Ranking. In dieser Klasse steckt im Wesent-
lichen die Intelligenz des Programms. Sie modelliert das bisherige Befragungsergebnis,
also die vorgeschlagenen Wörter und die zugehörigen Wahlhäufigkeiten. Bei einem Pro-
grammlauf erzeugt das
Responder-Objekt eine Instanz der Klasse Ranking und ordnet
diese seinem Attribut
ranking zu. Ranking enthält zwei öffentliche Attribute und ver-
schiedene öffentliche Methoden, mit denen das Befragungsergebnis verändert, abge-
fragt und gespeichert werden kann.
Das UML-Klassendiagramm in Abbildung 25.3 gibt die Struktur wieder.
Entscheidend ist, dass die Klasse
Ranking separat getestet werden kann. Dazu ist der Spei-
cherort der Moduldatei unerheblich. Sie kann auf einem beliebigen Rechner ausgeführt und
getestet werden, bevor sie auf den Server hochgeladen und in das Gesamtsystem integriert
wird.
<html>
<head>
<title>Wort des Jahres</title>
<meta http-equiv="Content-Type" content="charset=utf-8" />
</head>
<body bgcolor =#C0C0C0>
<font face="VERDANA,ARIAL,HELVETICA">
<h2>Suche nach dem Wort des Jahres</h2>
Bitte geben Sie Ihren Vorschlag ein und klicken Sie auf die
Schaltfl&auml;che.
<form action="http://localhost:8000/cgi-bin/wdj.py">
Mein Wort des Jahres: <input type="Text" name="word" size="25" > <br>
<input type="Submit" value="Abschicken">
</form>
</font>
</body>
</html>
?word=Schnupfen
687
25.3
Praxisbeispiel: Suche nach dem Wort des Jahres
Abb. 25.3: UML-Klassendiagramm für das Projekt »Wort des Jahres«
CGI-Skript
Das CGI-Skript verarbeitet die Eingabe des Besuchers der statischen Webseite und liefert
eine Antwort wie in Abbildung 25.2.
Skript:
#!/Python35/python.exe
# wdj.py
import cgi, cgitb
cgi t b.e n a b le( ) #1
from ranking import *
#2
RESPONSE = """Content-Type: text/html
<html>
<meta http-equiv="Content-Type" content="charset=utf-8" />
<head><title>Wort des Jahres</title></head>
<body >
<font face="VERDANA,ARIAL,HELVETICA">
<h2> Danke f&uuml;r Ihr Votum!</h2>
Hier sind die bisherigen Top Ten: <br>
{}
Ihr Vorschlag {} steht auf Platz {}.<br>
</font>
</body>
</h t ml> " " "
PATH = "wort_des_jahres/words.txt"
class Responder:
def __init__ (self, datafile):
form = cgi.FieldStorage()
self.word = form.getvalue("word")
self.ranking = Ranking(datafile) #3
Responder
word
respond()
Ranking
filename
voting
add()
getTop()
getRank()
save()
ranking

Get Python 3 - Lernen und professionell anwenden now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.