[Python-Leipzig] Parametrieren von Python Tests

Dr. Volker Jaenisch volker.jaenisch at inqbus.de
Di Nov 22 02:37:45 UTC 2011


Moin!

Ich eskaliere diese Diskusion mal an eine größere Gemeinde um etwas mehr Feedback zu bekommen.
Wir bei Inqbus haben eine Diskussion über Testing(Frameworks) ähnlich der Emacs vs. VI Debatte,
welche ja nach langer Zeit nun für den Emacs entschieden wurde :-).

Ich stellte bisher die Nose-Fraktion dar, Markus Zapke-Gründemann die pytest-Fraktion, zope.testing wird vertreten vom Maik Derstappen und
Thomas Massmann.
Es geht hier nicht um einen Schwanzlängenvergleich: Alle drei Frameworks erfüllen hervorragend ihren Zweck. Darüber sind sich alle Beteiligten
einig.

Es geht mir hier um die Frage ob diese Frameworks an sich sinnvoll sind oder ob ein wenig Selbstbeschränkung nicht gut täte?

Hier der Anlaß:

Es gibt aber auch bei Nose Dinge, die schwer zu verstehen sind:

So wäre es intuitiv eine Parametrisierung mit Nose so zu formulieren:

class TestCaseAction(object):

    def setUp(self):
        self.foo = ["bar", "bar1" ]

    def test_base_actions(self):
        for foo in self.foo:
                yield self.do_action, foo

    def do_action(self, foo):
        assert foo == bar

funktioniert aber nicht mit Fehler:
TestCaseAction has no attrib foo in line
>>>> for foo in self.foo:

Bugreport in
http://code.google.com/p/python-nose/issues/detail?id=233

Also kann man den ganzen schönen Überbau mit der setUp Methode vergessen, wenn man mit Nose Generator-Methoden arbeitet.
Ohne Generator-Methode funktioniert die Klasse. Das Einfügen des Generators führt also zu einem Seiteneffekt im Testcode.
Wollen wir so etwas?

Also mich kotzt das Testen mit Tetframeworks so langsam an.

Wozu schreiben wir Tests mit Nose/Pytest?
* Um eine neue implizite Programmiersprache (Nose/pytest) zu lernen?
* Um Testkonstrukte zu schreiben die komplexer sind als der Code den sie testen sollen?
* Aber wer testet den TestCode?

Es kann einfach nicht funktionieren, dass wir mit komplexeren Werkzeugen Test schreiben als wir Code haben, den wir testen wollen.
Komplexität meint hierbei nicht die Zeilen Code die ich hinschreibe, sondern auch alle die Zeilen die ich mir denken muss.
Also all die Zeilen, die nicht in der Art und Weise interpretiert werden wie das Python an sich tun würde und die iich im Vergleich
mit derm Source oftmals auch nicht einfach debuggen kann.
Wenn der Testcode nicht weniger komplex ist als der getestete Code, dann bringt er rein gar nichts ausser Portierungsproblemen
und noch mehr Code der zu warten ist.

Ich will saubere Tests schreiben, die auch jemand verstehen kann, der meinen sophisticated source-code nicht verstehen kann,
weil er evtl einen Bugreport schreiben will. Wenn ich demjenigen einen Test-Code vorsetze, der noch weniger verständlich und
debugbar ist als der Source, was soll das letztendlich bringen?

Das erste Mal bin ich auf dieses Problem gestoßen als ich mit Grok gearbeitet habe. Auch dort wird vieles inplizit
über Konvention geregelt und nicht explizit formuliert. Bei Grok habe ich es damals ja noch in Ansätzen verstanden,
weil die ZCML-Formulierung von Parametern oftmals einfacher durch impliziete Annahmen zu deklarieren waren als in XML.
Da wurde an gewissen Stellen Komplexität reduziert.

Aber auch in Punkto Grok/ZCML sind wir nach einiger Zeit auf den Trichter gekommen, dass explizit besser als Implizit ist.
Es ist also nicht das erst Mal, das wir vor so einer Art von Problem stehen.

Warum bin ich bei der Auswertung meiner wissenschftlichen Daten von awk auf Python umgestiegen und nicht auf Perl,
das die Weiterentwicklung von awk darstellen soll? Weil Python expliziter war!
Nun scheint es auch bei Python in zu sein auf die implizite Meta-Meta Eben zu klettern, koste es was es wolle.
Nichts gegen eine gut durchgezogene Meta-Ebene. Python Metaclasses sind ein absolutes Killer Feature.

Aber sowohl bei Nose als auch bei pytest sehe ich viel zu viele implizite Annahmen und das gerade bei einem Testframework,
welche am besten noch Code mit Meta-Classes testen soll.

Ich plädiere mal für Selbstbeschränkung. Wenn es keinen wirklich guten Grund gibt ein Testing Framewirk einzusetzen,
dann sollten Bordmittel also Unittest verwendet werden.

Haltet mich nur für einen alten konservativen Spinner. Ich habe absolut nichts gegen Frameworks die uns vorwärts bringen.
Ich habe aber etwas gegen Frameworks, welche
* unnötige Komplexität aufzwingen
* massive Einarbeitung erfordern
* keinem Standart genügen, und selber keiner sind

Beste Grüße

Volker

-- 
====================================================
   inqbus GmbH & Co. KG      +49 ( 341 ) 60013031
   Dr.  Volker Jaenisch      http://www.inqbus.de
   Karl-Heine-Str.   99      0 4 2 2 9    Leipzig
   N  O  T -  F Ä L L E      +49 ( 170 )  3113748
====================================================




Mehr Informationen über die Mailingliste Python-Leipzig