Test-Driven Development

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Also Unittests würde ich auf jeden Fall vor Metaklassen reinschieben, da sie von der Komplexität wesentlich einfacher sind. Es sind normale Funktionen, die ein bestimmtes Verhalten von Code prüfen - das ist alles. Das Problem bei Unittests ist, dass es eben Arbeit ist, die nicht direkt zum Bau deines Programmes beiträgt (naja, es gibt Test-First-Programming, das ist wohl noch am motivierendsten).
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

HWK hat geschrieben:Ja, vielleicht sollte man die Tests schreiben, wenn man ein Programm erweitert.
Nein, man sollte die Tests schreiben, *bevor* man den eigentlichen Programmcode erweitert (oder überhaupt erstellt). TDD funktioniert so (bzw. so habe ich es bisher verstanden), dass man das zu lösende Problem in einem Test formuliert und dann eine Implementierung schafft oder anpasst, damit diese das Problem löst.
HWK hat geschrieben:Wo seht Ihr die Vorteile von py-test bzw. nose gegenüber unittest?
Wie ich (glaube ich) schon schrieb: `unittest` zwingt einem eine Klassenstruktur auf, die meist nur viel Ballast bedeutet. Mit `py.test` wird alles als Testcode angesehen, was sich in Modulen und Callables verbirgt, die mit dem Präfix 'test_' beginnen. Das ist für mich momentan erstmal ausschlaggebend, bis ich andere oder weitere Anforderungen habe.
HWK hat geschrieben:Kennt denn jemand das Buch Test Driven Development von Kent Beck?
Ich habe nur "Extreme Programming Planen" von Kent Beck und Martin Fowler gelesen. Naja, es war interessant, aber nur bedingt auf Hobbyprogrammierer anwendbar.

Was mir Probleme bereitet, ist, dass es gerade im Java-Bereich sehr viele Beispiele für Testing gibt, im Python-Bereich aber eher wenig (insbesondere bzgl. Stubbing und Mocking).
poker hat geschrieben:
Y0Gi hat geschrieben: Achso, `py.test` nutze ich ebenfalls, da ich sehr schätze, dass es keine Vererbung voraussetzt und hübsch selbst alle Testmodule und -Callables findet. In irgendeinem Blog wurde es mit `unittest` und `nose` verglichen und `unittest` kam am besten weg
Ich schätze das war dann folgender Blog:
http://agiletesting.blogspot.com/2005/0 ... ttest.html
http://agiletesting.blogspot.com/2005/0 ... ctest.html
http://agiletesting.blogspot.com/2005/0 ... -tool.html
Exakt, danke.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

poker hat geschrieben:Wenn deine Software nur die Bestandteile nutzt (Die nicht von dir geschrieben sind), dann musst du die auch nicht testen! Es ist nämlich nicht deine Aufgabe auch fremde Libraries mit deinen Unit tests abzudecken.
Nein, das habe ich natürlich nicht vor. Aber ich möchte etwa prüfen, dass mein Code z.B. konkret SQLAlchemy korrekt anspricht und z.B. nur Ergebnisse mit den erwarteten Kriterien (Attribute, Anzahl, angewandte Filter) zurückliefert.
poker hat geschrieben:Dafür bittet es sich dann an Mocks zu schreiben.
Ja, da fehlt mir irgendwie der Einstieg anhand praktischer Beispiele. Insbesondere weil ich nicht weiß, auf welche Mock-Implementierung ich überhaupt aufsetzen soll.

Vorzugsweise möchte ich natürlich testen können, *ohne* eine Verbindung zu einer Datenbank oder über das Netzwerk aufbauen zu müssen; sowohl aus Zeit- als auch aus Verfügbarkeitsgründen.
poker hat geschrieben:Angenommen du hast eine Funktion oder Klasse die über `socket` auf sockets zugreift und in Abhängigkeit der Ergebnisse bestimmte Aktionen ausführt oder Zustände ändert. Jetzt kommt das Problem, das wenn du damit auf einen Externen $SERVER zugreifen der immer Bestimmte Daten zurückliefern muss. In dem Fall abstrahierst du `socket` und die erwarteten Daten von $SERVER in dem masse das deine Funktion genauso Arbeitet, als wenn du Tatsächlich `socket` mit $SERVER nutzen würdest.
Das heißt konkret, das du die erforderlichen Schnittstellen von `socket` nachschreibst die sich halt stat sich mit $SERVER verbindet, eben nur die von dir von echten $SERVER erwarteten Daten zurückliefert. Das ganze ist dann zuzusagen ein Mock - Eine Attrappe - den du deiner Funktion unterschiebst. Natürlich musst du diese Attrappe soweit nachbauen das auch die von dir erwarteten Fehler Codes/Exception wie beim Original geschmissen werden.
Ja, so stelle ich mir das auch vor. Hast du Beispielcode aus Projekten, in denen du sowas selbst mal geschrieben (oder gesehen) hast?
pug
User
Beiträge: 16
Registriert: Dienstag 4. September 2007, 17:00

Ich bin beim Surfen auf dem agiletesting Blog über folgenden Link gestolpert.

http://pycheesecake.org/wiki/PythonTest ... stingTools

Hier werden einige Frameworks für Mock Objects aufgelistet. Ein vernünftiges Tutorial fehlt mir allerdings auch noch. Ich programmiere gerade einen Pythonwrapper für ein CLI und könnte so etwas recht gut brauchen.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

YOGi hat geschrieben:Nein, man sollte die Tests schreiben, *bevor* man den eigentlichen Programmcode erweitert (oder überhaupt erstellt). TDD funktioniert so (bzw. so habe ich es bisher verstanden), dass man das zu lösende Problem in einem Test formuliert und dann eine Implementierung schafft oder anpasst, damit diese das Problem löst.
Das mag für einen Profi-Programmierer, der in einem Team arbeitet und die Programme weitergibt, zutreffen. Für einen Einzelkämpfer, der überwiegend Programme für sich erstellt, ist dies aber sicher überzogen. Dieser kann sicher nicht für jedes seiner Tools Unittests durchführen. Wenn überhaupt lohnt sich für ihn der Aufwand nur für Programme, die er häufig benutzt und auch verändert. Deshalb ist m.E. durchaus ein gutes Kriterium, ob sich Tests lohnen, ob ein Programm erweitert wird.
Für mich sehe ich ein weiteres Problem: Meine größeren Programme, die ich häufig und lange verwende und somit auch öfter anpasse, arbeiten meistens mit einer GUI wie wxPython oder Tkinter. Dafür Tests zu schreiben ist aber wesentlich aufwendiger, evtl. sogar mehr als den Programmcode selbst zu schreiben. Wahrscheinlich ist es hier effektiver, auf Tests zu verzichten und den Code dann anzupassen, wenn Fehler bei der Verwendung auftreten. Da die Programme ja normalerweise nicht weitergegeben werden und somit nur vom Entwickler verwendet werden, dürfte dies kein Problem darstellen. Das Testing erfolgt hier halt bei der Anwendung.
MfG
HWK
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Klar, für jedes Hobby- oder Wegwerf-Programm mag das nicht lohnen. Wenn man allersdings eine Library erstellt, die auch mal andere verwenden könnten, sieht das schon etwas anders aus.

Ich mache auch nur vereinzelt (und gewöhnlich nachträglich) Unittests, weil das bei Webanwendungen nicht so einfach ist wie z.B. eben einer Library ohne Web-Interface oder GUI. An sich halte ich es aber für richtig und sinnvoll und bemühe ich, das weiter auszuweiten. Muss man selbst entscheiden.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Ich muss mich korrigieren: `nose` ist in vieler Hinsicht `py.test` doch sehr ähnlich. Möglicherweise werde ich mich in Zukunft darauf stützen, da es z.B. auch das Coverage-Modul einbinden kann.
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

HWK hat geschrieben:Das mag für einen Profi-Programmierer, der in einem Team arbeitet und die Programme weitergibt, zutreffen. Für einen Einzelkämpfer, der überwiegend Programme für sich erstellt, ist dies aber sicher überzogen. Dieser kann sicher nicht für jedes seiner Tools Unittests durchführen. Wenn überhaupt lohnt sich für ihn der Aufwand nur für Programme, die er häufig benutzt und auch verändert.
Ich würde nicht sagen, dass es überzogen ist, denn eigentlich ist es nicht so viel Mehraufwand, wie man vielleicht denkt. Schließlich testest du deinen Code nach dem schreiben ja sowieso, meistens interaktiv und schaust, ob der Code das macht, was er soll. Also könntest du eigentlich auch gleich einen Unittest schreiben und ihn dann durchlaufen lassen.
Eine andere, pythonspezifische Form wären dann die doctests, hier kannst du ja einfach deine interaktive Testsession deines Programmes copy-and-pasten und fertig ist der Unittest.

(Ich gebe gerne zu, dass ich in der Praxis auch nicht immer Unittests schreibe, aber in diesem Thread geht es ja um "best practices")
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Das trifft sicher für reine Konsolenanwendungen zu. Es wird aber schon schwieriger, wenn es um Programme für ein lokales Netz oder gar das Internet geht. Sehr schwierig ist es aber sicher für Programme mit GUI. Das ist natürlich mit pywinauto, Ranorex und co. alles möglich, aber aufwendig. Ich habe solche Tools mehrfach verwendet, um Drittprogramme zu steuern, und das lief nie so einfach wie in den Demos.
Dass ich doctests für interessant halte, sagte ich bereits. Ich glaube aber, der Mehraufwand für unittests ist nicht mehr so groß und man hat damit wohl doch mehr Möglichkeiten.
MfG
HWK
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

HWK hat geschrieben:Es wird aber schon schwieriger, wenn es um Programme für ein lokales Netz oder gar das Internet geht.
Genau da setzt Mocking an, siehe weiter oben. Dabei geht es nur darum, dass an etwas die gewünschten Aufrufe abgesetzt werden; insgeheim passiert dann aber nichts, d.h. eine tatsächliche Verbindung wird nicht aufgebaut, sondern höchstens simuliert.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Ja, Mocking hatte ich mir nach einer von pokers Antworten schon angeschaut. Das Problem ist aber auch hier: Wenn man die Datenrückgabe eines Servers simulieren will, ist das sehr aufwendig. Wenn ich nichts simuliere, ist der Test nur sehr grob.
MfG
HWK
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Das stimmt, aufwendig ist es. Es ist aber auch aufwendig, einen Fehler zu finden, der sich unbemerkt vor ein paar Tagen eingeschlichen hat. Insbesondere, wenn du gegen fremde Webservices programmierst, ist praktisch zu sehen, ob der Fehler in deinem Code liegt oder auf seiten des Webservice.

Unittests sind allgemein aufwendig, die Theorie ist halt, dass es noch aufwendiger ist, ständig nach Fehlern zu suchen und von Hand zu testen.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Ich sehe schon ein, dass Testing sinnvoll ist. Ich werde auch versuchen, für einfachere meiner Programmen mal eine unittest zu schreiben, um Erfahrungen damit zu sammeln und evtl. bei neuen Projekten von Anfang an Tests mitzuschreiben. Ich denke aber, was in diesem Thread ja auch schon angeklungen ist, dass man als Hobbyprogrammierer Kompromisse eingehen kann und muss. Zwei meiner am meisten verwendeten größeren Programme sind mit GUI und Netzwerk-/Internet-Anbindung. Hierfür unittests zu haben, wäre schon toll, da ich hier häufiger etwas anpassen möchte, ich mich wegen möglicher Fehler aber doch damit etwas zurückhalte. Für diese Programme, die jeweils um die 70 KB Quellcode enthalten, nachträglich Test zu schreiben, halte ich aber z.B. für mich als Einzelkämpfer schlicht für nicht praktikabel.
MfG
HWK
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Just heute drüber gestolpert: http://pypi.python.org/pypi/MiniMock
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Y0Gi hat geschrieben:Ich mache auch nur vereinzelt (und gewöhnlich nachträglich) Unittests, weil das bei Webanwendungen nicht so einfach ist
Jep, das stimmt. Allerdings bietet z.B. django dazu einige Handreichungen:
http://www.djangoproject.com/documentation/testing/
Genial finde ich den "test client" mit dem man Request konstruiert und dann den Response überprüfen kann... Eine sehr schöne Sache...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

HWK hat geschrieben: Für mich sehe ich ein weiteres Problem: Meine größeren Programme, die ich häufig und lange verwende und somit auch öfter anpasse, arbeiten meistens mit einer GUI wie wxPython oder Tkinter. Dafür Tests zu schreiben ist aber wesentlich aufwendiger, evtl. sogar mehr als den Programmcode selbst zu schreiben.
Das ist klar und haben Tests auch ansich. Ein Test der 100% eine Applikation abdeckt ist immer umfangreicher als der zu testenden Code (Meiner Erfahrung nach). wxPython Widgets sind, wie im geposteten link vorgestellt, garnicht so kompliziert zu Testen. Das liegt auch mit daran das Python eine dynamische Sprach ist, es kein Private/Protected Mechanismus gibt und dadurch bedingt "extrem" einfach macht sowas zu testen :) Aber klar, es ist immer noch umfangreicher und schwieriger als CLI Programme zu Unit testen. Ob sich das für einen Hobby programmiere loht muss man von Fall zu Fall abwägen.

HWK hat geschrieben: Wahrscheinlich ist es hier effektiver, auf Tests zu verzichten und den Code dann anzupassen, wenn Fehler bei der Verwendung auftreten.
Ich denke IMO eher nicht. Es gab doch mal so ein Sprichwort das besagt das auf ein Bugfix 10 neue Bugs hinzukommen. Unit tests vermeiden das halt, weil man dadurch Änderungen verifizieren kann.

Zugegeben, ich mag die "Sicherheit" die mir ein Unit test bietet sehr. So kann ich entspant Änderungen machen und mit den Test gegenchecken ob ich nicht doch irgendwo ein Bug gebaut habe.

Y0Gi hat geschrieben: Ich mache auch nur vereinzelt (und gewöhnlich nachträglich) Unittests, weil das bei Webanwendungen nicht so einfach ist wie z.B. eben einer Library ohne Web-Interface oder GUI.
Ja, Webanwendungen sind echt ein Problem! Das ist ingrunde IMO auch einer der Bereiche wo man nicht mehr verhältnismäßig (=Zeit, Umfang) gut mit Mocking arbeiten kann. Da ist es "angebracht" sich gleich eine richtige Testumgebung mit Server, DB, etc einzurichten. Aber ob der Aufwand sich dann auch rechnet...? Gute frage...Was sagen die Pocoo Devs? Wie macht ihr das mit Pocoo? Wie sieht es mit MoinMoin aus? Irgendwie finde ich das da gerade irgendwie düster (Kommt mir vor als ob da nicht wirklich alles abgedeckt wird).

HWK hat geschrieben:Ich werde auch versuchen, für einfachere meiner Programmen mal eine unittest zu schreiben, um Erfahrungen damit zu sammeln und evtl. bei neuen Projekten von Anfang an Tests mitzuschreiben.
Das würde ich dir auch empfehlen. Wenn du dann auf den Geschmack gekommen bist, willst du nie wieder anders arbeiten :)
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

poker hat geschrieben:Es gab doch mal so ein Sprichwort das besagt das auf ein Bugfix 10 neue Bugs hinzukommen.
Das erinnert mich an die Fvwm-Manpage:
BUGS
As of fvwm version 2.4.0 there were exactly 71.8 unidentified bugs.
Since then 22.825 bugs have been fixed. Assuming that there are at
least 10 unidentified bugs for every identified one, that leaves us
with 71.8 - 22.825 + 10 * 22.825 = 277.225 unidentified bugs. If we
follow this to its logical conclusion we will have an infinite number
of unidentified bugs before the number of bugs can start to diminish,
at which point the program will be bug-free. Since this is a computer
program infinity = 3.4028e+38 if you do not insist on double-precision.
At the current rate of bug discovery we should expect to achieve this
point in 4.27e+27 years. I guess we better plan on passing this thing
on to our children...
:)
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Das einzige Problem an Unittests sind fehlerhafte Tests. Ich meine mich zu erinnern, daß Guido im Rahmen der Python3000-Entwicklung einige in CPython aufgefallen waren, die lediglich Bugs oder fragwürdige Implementationen der CPython-Implementierung festhielten. (Finde leider gerade die Verweise nicht mehr...)
Antworten