2009-03-22 7 views
9

Sagen wir, dass ich meine Code-Basis zu einem so hohen Maß an Unit-Test-Abdeckung hat, wie sinnvoll. (Ab einem bestimmten Punkt hat eine zunehmende Abdeckung keinen guten ROI.)Wie man "Performance-basierte" (Benchmark) Unit-Tests in Python macht

Als nächstes möchte ich die Leistung testen. Benchmark-Code, um sicherzustellen, dass neue Commits die Dinge nicht unnötigerweise verlangsamen. Ich war sehr fasziniert von Safari zero tolerance policy für Verlangsamungen von commits. Ich bin mir nicht sicher, ob das Maß an Geschwindigkeitsbegabung für die meisten Projekte einen guten ROI bringt, aber ich möchte zumindest darauf hingewiesen werden, dass eine Geschwindigkeitsregression stattgefunden hat, und in der Lage sein, eine Entscheidung darüber zu treffen.

Die Umgebung ist Python unter Linux, und ein Vorschlag, der auch für BASH-Skripte funktioniert, würde mich sehr freuen. (Aber Python ist der Schwerpunkt.)

Antwort

7

Sie möchten Leistungstests auf Systemebene durchführen, wenn möglich - Testen Sie Ihre Anwendung als Ganzes, im Kontext, mit Daten und Verhalten so nah wie möglich an der Produktion zu verwenden.

Dies ist nicht einfach, und es wird noch schwieriger, es zu automatisieren und konsistente Ergebnisse zu erhalten.

Darüber hinaus können Sie keine VM für Leistungstests verwenden (es sei denn, Ihre Produktionsumgebung wird in VMs ausgeführt und selbst dann müssen Sie die VM auf einem Host ausführen, auf dem sonst nichts läuft).

Wenn Sie sagen, Leistung Unit-Testing, das kann wertvoll sein, aber nur, wenn es verwendet wird, um ein Problem zu diagnostizieren, das wirklich auf einer Systemebene existiert (nicht nur im Kopf des Entwicklers).

Auch die Leistung von Einheiten in Komponententests spiegelt manchmal nicht ihre Leistung im Kontext wider, so dass es möglicherweise überhaupt nicht sinnvoll ist.

+0

+1: AND ... Leistungstests sind nur dann sinnvoll, wenn Sie absolute Leistungsziele haben. Selten im Allgemeinen; unverzichtbar in militärischen und elektronischen Kontrollsystemen. –

+1

Sorry @ S.Lott - da stimme ich dir absolut nicht zu. Immer wenn mehr als 2 oder 3 Personen an einem Projekt arbeiten und es einen Endnutzer gibt, der Erwartungen an die Reaktionsfähigkeit hat, werden die Teams gut daran tun, ihre Leistung automatisch an den Zielen zu messen. Andernfalls wird Feature nach Feature hinzugefügt, ohne dass die Auswirkungen auf die Leistung und das Kundenerlebnis wirklich verstanden werden. –

2

MarkR hat Recht ... das Durchführen von Tests in der realen Welt ist der Schlüssel und kann in Komponententests etwas unpassend sein. Nachdem Sie das gesagt haben, werfen Sie einen Blick auf das Modul cProfile in der Standardbibliothek. Es wird zumindest nützlich sein, Ihnen einen relativen Sinn von commit-to-commit zu geben, wie schnell die Dinge laufen, und Sie können es innerhalb eines Komponententests ausführen, obwohl Sie natürlich Ergebnisse in den Details erhalten, die den Overhead enthalten des Unit-Test-Framework selbst.

In allem, wenn Ihr Ziel Null-Toleranz ist, benötigen Sie etwas viel robuster als dies ... cProfile in einem Komponententest wird es überhaupt nicht schneiden, und kann irreführend sein.

2

Wenn ich Leistungstests durchführe, habe ich im Allgemeinen eine Testsuite mit Dateneingängen und messe, wie lange das Programm benötigt, um jedes zu verarbeiten.

Sie können die Leistung täglich oder wöchentlich protokollieren, aber ich finde es nicht besonders nützlich, sich um die Leistung zu sorgen, bis alle Funktionen implementiert sind.

Wenn die Leistung zu schlecht ist, dann brechen Sie cProfile aus, führen Sie es mit den gleichen Dateneingaben, und versuchen Sie, wo die Engpässe zu sehen sind.

5

Während ich zustimme, dass die Testleistung auf Systemebene letztendlich relevanter ist, wenn Sie UnitTest-Style-Load-Tests für Python durchführen möchten, erfüllt FunkLoad http://funkload.nuxeo.org/ genau das.

Mikro-Benchmarks haben ihren Platz, wenn Sie versuchen, eine bestimmte Aktion in Ihrer Codebasis zu beschleunigen. Das Durchführen nachfolgender Leistungseinheitstests ist eine nützliche Methode, um sicherzustellen, dass diese Aktion, die Sie gerade optimiert haben, nicht unbeabsichtigt bei zukünftigen Commits in der Leistung zurückgeht.