Test-Driven Development
-
- 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
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:Ja, vielleicht sollte man die Tests schreiben, wenn man ein Programm erweitert.
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:Wo seht Ihr die Vorteile von py-test bzw. nose gegenüber unittest?
Ich habe nur "Extreme Programming Planen" von Kent Beck und Martin Fowler gelesen. Naja, es war interessant, aber nur bedingt auf Hobbyprogrammierer anwendbar.HWK hat geschrieben:Kennt denn jemand das Buch Test Driven Development von Kent Beck?
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).
Exakt, danke.poker hat geschrieben:Ich schätze das war dann folgender Blog: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
http://agiletesting.blogspot.com/2005/0 ... ttest.html
http://agiletesting.blogspot.com/2005/0 ... ctest.html
http://agiletesting.blogspot.com/2005/0 ... -tool.html
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: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.
Ja, da fehlt mir irgendwie der Einstieg anhand praktischer Beispiele. Insbesondere weil ich nicht weiß, auf welche Mock-Implementierung ich überhaupt aufsetzen soll.poker hat geschrieben:Dafür bittet es sich dann an Mocks zu schreiben.
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.
Ja, so stelle ich mir das auch vor. Hast du Beispielcode aus Projekten, in denen du sowas selbst mal geschrieben (oder gesehen) hast?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.
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.
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.
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.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.
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
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.
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.
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.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.
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")
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
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
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.HWK hat geschrieben:Es wird aber schon schwieriger, wenn es um Programme für ein lokales Netz oder gar das Internet geht.
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
MfG
HWK
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.
Unittests sind allgemein aufwendig, die Theorie ist halt, dass es noch aufwendiger ist, ständig nach Fehlern zu suchen und von Hand zu testen.
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
MfG
HWK
Just heute drüber gestolpert: http://pypi.python.org/pypi/MiniMock
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Jep, das stimmt. Allerdings bietet z.B. django dazu einige Handreichungen:Y0Gi hat geschrieben:Ich mache auch nur vereinzelt (und gewöhnlich nachträglich) Unittests, weil das bei Webanwendungen nicht so einfach ist
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...
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 testenHWK 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.

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.HWK hat geschrieben: Wahrscheinlich ist es hier effektiver, auf Tests zu verzichten und den Code dann anzupassen, wenn Fehler bei der Verwendung auftreten.
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.
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).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.
Das würde ich dir auch empfehlen. Wenn du dann auf den Geschmack gekommen bist, willst du nie wieder anders arbeitenHWK 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.

- Rebecca
- User
- Beiträge: 1662
- Registriert: Freitag 3. Februar 2006, 12:28
- Wohnort: DN, Heimat: HB
- Kontaktdaten:
Das erinnert mich an die Fvwm-Manpage:poker hat geschrieben:Es gab doch mal so ein Sprichwort das besagt das auf ein Bugfix 10 neue Bugs hinzukommen.
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
Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
- 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...)