Einheitentestinfrastruktur für ein Python-Modul

8

Ich schreibe ein Python-Modul und möchte es Unit-Test machen. Ich bin neu in Python und etwas durch die verfügbaren Optionen verblüfft.

Zur Zeit möchte ich meine Tests als doctests schreiben, da ich eher den deklarativen als den imperativen Stil mag ( aber fühlen Sie sich frei, mich dieser Vorliebe zu entfremden, wenn es falsch informiert wird). Dies wirft jedoch einige Fragen auf:

  1. Wo soll ich die Tests ablegen? In derselben Datei wie der Code, den sie testen (oder in Docstrings für Doctests)? Oder ist es besser, sie in ihrem eigenen Verzeichnis zu trennen?
  2. Wie kann ich alle Tests im gesamten Modul über die Befehlszeile auf einmal ausführen?
  3. Wie kann ich die Codeabdeckung der Testsuite melden?
  4. Irgendwelche anderen Best Practices, auf die ich bei Komponententests in Python achten sollte?
fmark 14.07.2010, 02:01
quelle

6 Antworten

12
  

fühlen Sie sich frei, mich davon zu entkräften   Präferenz, wenn es falsch informiert wird

Ich glaube, ich habe doctest extensiver verwendet ( way dehnt seine Grenzen für den beabsichtigten Einsatz) als jeder andere Open-Source-Entwickler, zumindest innerhalb eines einzigen Projekts - all Die Tests in meinem Projekt gmpy sind Dokumententests. Es war brandneu zu der Zeit, als gmpy gestartet wurde, es schien ein großartiger kleiner Trick zu sein, und wenn sich etwas lohnt, sollte man es im Übermaß tun - richtig? -)

Falsch. Mit Ausnahme von gmpy , wo das Wiederholen von allem als richtige Komponententests zu viel Nacharbeit wäre, habe ich diesen Fehler nie wieder gemacht: In diesen Tagen verwende ich Komponententests als Komponententests und doctests, um meine Dokumente zu überprüfen, da sie ' war immer dazu gedacht, benutzt zu werden. Was Doctorts tun (vergleichen Sie ein erwartetes mit einem tatsächlichen Ergebnis für die Gleichheit - das ist alles) ist einfach keine gute oder solide Basis, um eine solide Test-Suite zu erstellen. Es war nie anders gedacht.

Ich würde Ihnen empfehlen, sich die Nase anzusehen. Das Modul unittest im neuen Python 2.7 ist viel reicher und schöner, und wenn Sie auf 2.4, 2.5 oder 2.6 festsitzen, können Sie die neuen Funktionen weiterhin mit dem unittest2 , die Sie herunterladen und installieren können; nose ergänzt unittest ziemlich gut.

Wenn du nicht untestest stehen kannst (aber - probiere es aus, es wächst auf dir! -), probiere es vielleicht py.test , ein alternatives Paket mit einer ziemlich anderen Philosophie.

Aber bitte , dehnt doctest nicht aus, um andere Dinge als Beispiele in Dokumenten zu testen! Der Gleichheitsvergleich wird dir viel zu oft im Weg stehen, wie ich bei meinen (metaphorischen ;-) Ausgaben in gmpy ...

erfahren habe     
Alex Martelli 14.07.2010, 02:15
quelle
3

Ich mag Doctests aus diesen Gründen nicht:

  • Sie können keine Teilmenge der Tests ausführen. Wenn ein Test fehlschlägt, ist es sinnvoll, nur einen Test durchzuführen. Doctest bietet keine Möglichkeit, das zu tun.
  • Wenn ein Fehler in der Mitte des Doctests auftritt, stoppt die ganze Sache. Ich würde lieber alle Ergebnisse sehen, um zu entscheiden, wie man einen Bruch anpackt.
  • Der Codierungsstil ist stilisiert und muss druckbare Ergebnisse haben.
  • Ihr Code wird auf eine spezielle Art und Weise ausgeführt, so dass es schwieriger ist, darüber nachzudenken, wie er ausgeführt wird, dass es schwieriger ist, Helfer hinzuzufügen, und dass es schwieriger ist, die Tests zu programmieren.

Diese Liste wurde aus meinem Blogpost Dinge, die ich nicht an doctest mag , wo es noch mehr gibt, und ein langer Faden von Kommentaren diskutiert die Punkte.

Über die Berichterstattung: Ich glaube nicht, dass es ein Coverage-Tool für Python gibt, das die Abdeckung in Doctests messen wird. Aber da sie einfach lange Listen von Anweisungen ohne Verzweigungen oder Schleifen sind, ist das ein Problem?

    
Ned Batchelder 14.07.2010 02:25
quelle
2

Ich habe den Verdacht, dass Alex mir auf der Programmierer-Kurve ein gutes Stück voraus sein könnte, aber wenn Sie die Perspektive von jemandem mit etwas Python-Erfahrung (als "Benutzer" und nicht als Experte oder Evangelist) haben wollen In der gleichen Liga sind meine Ergebnisse über Unit-Tests ziemlich genau die gleichen.

Doctests könnten sich am Anfang gut für einfache Tests anhören, und ich ging in diese Richtung für ein persönliches Projekt zu Hause, weil es anderswo empfohlen wurde. Bei der Arbeit benutzen wir die Nase (obwohl so eingepackt und eingewickelt, hatte ich den Eindruck, dass wir pyUnit bis vor nicht allzu langer Zeit benutzt hatten), und vor ein paar Monaten bin ich auch zu Hause in die Nase gezogen.

Die anfängliche Rüstzeit und der Verwaltungsaufwand und die Trennung vom eigentlichen Code mag am Anfang unnötig erscheinen, besonders wenn Sie etwas testen, das keine so große Codebase ist, aber auf lange Sicht habe ich es Ich fand, dass Doctests jeder einzelnen Umstrukturierung oder Umstrukturierung, die ich durchführen wollte, im Weg standen, eher schwierig zu verwalten, praktisch unmöglich zu skalieren und die anfänglichen Einsparungen sehr schnell auszugleichen. Und ja, ich bin mir bewusst, dass Komponententests nicht mit Integrationstests identisch sind, aber Dopingtests neigen dazu, Ihre Einheiten für Sie eher zu streng zu definieren. Sie sind auch nicht gut für Unit-basierte Agile geeignet, wenn Sie sich jemals dafür entscheiden, dass es sich um ein gültiges Skizzierwerkzeug oder Dev-Modell handelt.

Es kann ein bisschen dauern, bis Sie Ihre Unit-Tests planen und verfeinern, je nachdem, wie pyUnit oder die Nase Sie steuern, aber selbst auf kurze Sicht werden Sie feststellen, dass es Ihnen auf vielen Ebenen hilft. Ich weiß, dass es für mich getan hat, und ich bin relativ neu in der Komplexität und dem Umfang der Codebasis, an der ich gerade arbeite. Muss nur die Zähne für die ersten paar Wochen zusammenbeißen.

    
ThE_JacO 14.07.2010 05:36
quelle
1

Sehen Sie sich für die Abdeckung die ausgezeichnete coverage.py an.

Sonst ist alles, was Alex Martelli geschrieben hat, sehr aufschlussreich.

    
bstpierre 14.07.2010 02:26
quelle
1

doctests eignen sich hervorragend für schnelle, kleinere Komponententests, die beschreiben, was einige grundlegende Verwendungen der fraglichen Objekte sind (wie sie in Docstrings angezeigt werden und daher helfen (was auch immer) usw.).

Ich persönlich habe umfangreiche und gründlichere Tests gefunden, um mit dem unittest-Modul effektiver zu sein, und nun hat das 2.7-Modul (zurück zu unittest2 portiert) noch praktischere Behauptungen. Mit dem Einheitentest-Framework können Sie Testsuiten und ein so komplexes Szenario erstellen, wie Sie möchten, und ganze Bereiche unterschiedlicher Tests auf einmal abdecken (über die Befehlszeile)

coverage.py , von Ned Batchelder und @bstpierre erwähnt, wird mit beiden funktionieren, und ich empfehle es für zu sehen, was Sie vom Code getestet haben und was nicht. Sie können es in ein CI-System (d. H. Hudson oder was auch immer Sie gerne verwenden) hinzufügen, um zu verfolgen, was abgedeckt ist und nicht, und die HTML-Berichte sind fantastisch, um zu sehen, was nicht mit Testabdeckung getroffen wurde. Coverage unterstützt die Junit-XML-Ausgabe, die viele CI-Systeme wissen, um fortlaufende Chartergebnisse bereitzustellen, damit Sie sehen, wie sich der Build im Laufe der Zeit verbessert oder verschlechtert.

    
heckj 14.07.2010 02:31
quelle
0

Ich stimme all den oben genannten Punkten zu, die bei Doktest nicht Skalierung betreffen, und ich bleibe lieber bei Unittest.

Ein Tipp, den ich beitragen kann, besteht darin, die Komponententests aus dem Code handling __name__ == "__main__ aufzurufen. Wenn die Testdatei also als Skript ausgeführt wird, führt sie ihre Tests aus.

zB:

%Vor%     
Andy Dent 14.07.2010 08:49
quelle