Best Practices für Leistungstests beim Ausführen von TDD?

8

Ich arbeite an einem Projekt, das eine Leistungsoptimierung dringend benötigt.

Wie schreibe ich einen Test, der fehlschlägt, wenn meine Optimierungen die Geschwindigkeit des Programms nicht verbessern?

Um ein wenig zu erläutern:

Das Problem besteht nicht darin, zu ermitteln, welche Teile optimiert werden sollen. Ich kann dafür verschiedene Profiling- und Benchmarking-Tools verwenden.

Das Problem besteht darin, automatisierte Tests zu verwenden, um zu dokumentieren, dass eine bestimmte Optimierung tatsächlich die beabsichtigte Wirkung hatte. Es wäre auch sehr wünschenswert, wenn ich die Testsuite nutzen könnte, um später mögliche Leistungsregressionen zu entdecken.

Ich nehme an, ich könnte einfach meine Profiling-Tools ausführen, um einige Werte zu erhalten, und dann behaupten, dass mein optimierter Code bessere Werte liefert. Das offensichtliche Problem dabei ist jedoch, dass Benchmark-Werte keine harten Werte sind. Sie variieren mit der lokalen Umgebung.

Also, ist die Antwort, immer dieselbe Maschine zu benutzen, um diese Art von Integrationstests durchzuführen? In diesem Fall müssten Sie dennoch etwas Unschärfe in den Ergebnissen berücksichtigen, da Benchmark-Ergebnisse auch auf derselben Hardware variieren können. Wie dann dies zu berücksichtigen?

Oder vielleicht ist die Antwort, ältere Versionen des Programms zu behalten und die Ergebnisse vorher und nachher zu vergleichen? Dies wäre meine bevorzugte Methode, da es meist umweltunabhängig ist. Hat jemand Erfahrung mit diesem Ansatz? Ich denke, es wäre nur nötig, eine ältere Version beizubehalten, wenn alle Tests bestanden werden können, wenn die Leistung der neuesten Version mindestens so gut ist wie die vorherige Version.

    
KaptajnKold 15.04.2009, 13:11
quelle

9 Antworten

5

Ich vermute, dass das Anwenden von TDD auf die Laufwerksleistung ein Fehler ist. Verwenden Sie es auf jeden Fall, um zu einem guten Design- und Arbeitscode zu kommen, und verwenden Sie die im Laufe von TDD geschriebenen Tests, um fortlaufende Korrektheit sicherzustellen - aber sobald Sie einen durchdachten Code und eine solide Testreihe haben, sind Sie in guter Verfassung zu tunen, und verschiedene (von TDD) Techniken und Werkzeuge treffen zu.

TDD bietet Ihnen ein gutes Design, zuverlässigen Code und ein Sicherheitsnetz für die Testabdeckung. Das bringt Sie in einen guten Ort für das Tuning, aber ich denke, dass Sie aufgrund der Probleme, die Sie und andere genannt haben, Sie nicht viel weiter auf dem Abstimmungsweg hinbringen werden. Ich sage das als ein großer Fan und Befürworter von TDD und einer Praktizierenden.

    
Carl Manaster 16.04.2009 17:35
quelle
3

Zuerst müssen Sie einige Kriterien für eine akzeptable Leistung festlegen, dann müssen Sie einen Test entwickeln, der diese Kriterien bei der Verwendung des vorhandenen Codes nicht erfüllt, dann müssen Sie Ihren Code für die Leistung optimieren, bis er den Test besteht. Sie werden wahrscheinlich mehr als ein Kriterium für die Leistung haben, und Sie sollten sicherlich mehr als einen Test haben.

    
Ed Guiness 15.04.2009 13:15
quelle
3

In vielen Serveranwendungen (möglicherweise nicht in Ihrem Fall) tritt ein Leistungsproblem nur unter gleichzeitigem Zugriff und unter Last auf. Das Messen der absoluten Zeit, die eine Routine ausführt und versuchen, sie zu verbessern, ist daher nicht sehr hilfreich. Es gibt Probleme mit dieser Methode auch in Singlethread-Anwendungen. Das Messen der absoluten Routinezeit hängt von der Uhr ab, die die Plattform bereitstellt, und diese sind nicht immer sehr genau ; Sie verlassen sich besser auf die durchschnittliche Zeit, die eine Routine braucht.

Mein Rat ist:

Obwohl Sie Komponententests verwenden könnten, um einige nicht funktionale Aspekte Ihrer Anwendung zu erstellen, denke ich, dass der oben angegebene Ansatz bessere Ergebnisse während des Optimierungsprozesses liefert. Wenn Sie in Ihren Komponententests zeitbezogene Assertionen eingeben, müssen Sie einige sehr angenäherte Werte wählen: Die Zeit kann abhängig von der Umgebung variieren, die Sie zum Ausführen der Komponententests verwenden. Sie möchten nicht, dass Tests nur deshalb fehlschlagen, weil einige Ihrer Kollegen minderwertige Hardware verwenden.

Beim Tuning geht es darum, die richtigen Dinge zu finden. Sie verfügen bereits über einen funktionierenden Code. Wenn Sie leistungsbezogene Assertions a posteriori platzieren und keine kritischen Codeabschnitte einrichten, können Sie viel Zeit mit der Optimierung nicht wichtiger Teile Ihrer Anwendung verlieren.

>     
Dan 15.04.2009 14:15
quelle
2

Notieren Sie die Laufzeit des aktuellen Codes.

%Vor%     
Rik 15.04.2009 13:16
quelle
1

Führen Sie die Tests + Profilerstellung im CI-Server aus. Sie können Auslastungstests auch regelmäßig ausführen.

Sie sind besorgt über Unterschiede (wie Sie erwähnt haben), also geht es nicht darum, einen absoluten Wert zu definieren. Haben Sie einen zusätzlichen Schritt, der die Leistungsmesswerte dieses Laufs mit denen des letzten Builds vergleicht und die Unterschiede als% meldet. Sie können eine rote Flagge für wichtige Zeitvariationen auslösen.

Wenn Sie sich um die Leistung sorgen, sollten Sie klare Ziele haben, die Sie erfüllen und durchsetzen möchten. Sie sollten diese mit Tests am Gesamtsystem messen. Selbst wenn Ihre Anwendungslogik schnell ist, haben Sie möglicherweise Probleme mit der Ansicht, die dazu führt, dass Sie das Ziel verfehlen. Sie können es auch mit dem Differenzen-Ansatz kombinieren, aber für diese würden Sie weniger Toleranz gegenüber Zeitschwankungen haben.

Beachten Sie, dass Sie denselben Prozess in Ihrem Entwicklungscomputer ausführen können, indem Sie nur die vorherigen Läufe auf diesem Computer verwenden und keine gemeinsame Ausführung zwischen den Entwicklern.

    
eglasius 16.04.2009 10:07
quelle
0

Für das Tuning selbst können Sie den alten und den neuen Code direkt vergleichen. Aber behalte beide Kopien nicht herum. Das klingt nach einem Albtraum, den es zu bewältigen gilt. Außerdem vergleichen Sie nur eine Version mit einer anderen Version. Es ist möglich, dass eine Änderung der Funktionalität Ihre Funktion verlangsamt, und das ist für die Benutzer akzeptabel.

Persönlich habe ich noch nie Leistungskriterien vom Typ 'muss schneller sein als die letzte Version', weil es so schwer zu messen ist.

Sie sagen: "Sie brauchen dringend eine Leistungsoptimierung". Woher? Welche Anfragen? Welche Funktionen? Wer sagt, das Geschäft, die Benutzer? Was ist eine akzeptable Leistung? 3 Sekunden? 2 Sekunden? 50 Millisekunden?

Ausgangspunkt für jede Leistungsanalyse ist das Definieren der Kriterien für bestanden / nicht bestanden. Sobald Sie dies haben, können Sie die Leistungstests automatisieren.

Für die Zuverlässigkeit können Sie einen (einfachen) statistischen Ansatz verwenden. Führen Sie beispielsweise dieselbe Abfrage unter denselben Bedingungen 100 Mal aus. Wenn 95% von ihnen in weniger als n Sekunden zurückkehren, ist das ein Pass.

Persönlich würde ich dies zur Integrationszeit tun, entweder von einer Standardmaschine oder dem Integrationsserver selbst. Notieren Sie die Werte für jeden Test irgendwo (Tempomat hat einige nette Funktionen für diese Art von Sache). Wenn Sie dies tun, können Sie sehen, wie die Leistung im Laufe der Zeit und mit jedem Build fortschreitet. Sie können sogar ein Diagramm erstellen. Manager mögen Diagramme.

Es ist immer schwierig, eine stabile Umgebung zu haben, wenn Sie Leistungstests durchführen, unabhängig davon, ob Sie automatisierte Tests durchführen oder nicht. Sie werden dieses spezielle Problem haben, egal wie Sie sich entwickeln (TDD, Waterfall, etc).

    
Matthew Farwell 17.04.2009 07:11
quelle
0

Ich bin noch nicht mit dieser Situation konfrontiert;) Aber wenn ich es täte, würde ich so vorgehen. (Ich glaube, ich habe das aus Dave Astels Buch gelesen)

Schritt # 1: Stellen Sie eine Spezifikation für "akzeptable Leistung" auf, also könnte das zum Beispiel bedeuten: "Der Benutzer muss in der Lage sein, Y in N Sekunden (oder Millisekunden) auszuführen"
Schritt 2: Schreiben Sie jetzt einen fehlgeschlagenen Test. Verwenden Sie Ihre freundliche Timer-Klasse (z. B. .NET hat die StopWatch-Klasse) und Assert.Less(actualTime, MySpec)
Schritt 3: Wenn der Test bereits bestanden hat, sind Sie fertig. Wenn rot, müssen Sie optimieren und grün machen. Sobald der Test grün wird, ist die Leistung jetzt "akzeptabel".

    
Gishu 20.04.2009 15:08
quelle
0

kent beck und sein Team haben alle Tests in TDD automatisiert.

hier für die Leistungsprüfung können wir auch die Tests in TDD automatisieren.

Die Kriterien hier in der Leistungsprüfung sind wir sollten die Ja oder Nein Fälle

prüfen

Wenn wir die Spezifikationen gut kennen, können wir sie auch in TDD automatisieren

    
Ramkrishna 09.01.2012 06:58
quelle
0

Obwohl ich weitgehend mit der Antwort von Carl Manaster übereinstimme, ist es mit modernen Tools möglich, einige von den Vorteilen zu profitieren, die TDD für Funktionstests in Leistungstests bietet.

Mit den meisten modernen Performance-Test-Frameworks (die meisten meiner Erfahrung ist mit Gatling , aber ich glaube, dass das gleiche gilt für neuere Versionen der meisten Leistungstest Frameworks), ist es möglich, automatisierte Leistungstests in den Build der fortlaufenden Integration zu integrieren und so zu konfigurieren, dass der CI-Build fehlschlägt, wenn die Leistungsanforderungen nicht erfüllt werden.

Wenn Sie also vorab vereinbaren können, was Ihre Leistungsanforderungen sind (was bei manchen Anwendungen durch SLAs, die mit Benutzern oder Kunden vereinbart wurden, möglich ist), können Sie schnell Feedback erhalten, wenn eine Änderung zu einem Leistungsproblem geführt hat das brauchen Leistungsverbesserungen.

Gute Leistungsanforderungen sind wie folgt: "Bei 5000 Bestellungen pro Stunde sollten 95% der Benutzerfahrten nicht mehr als 10 Sekunden Wartezeit umfassen und kein Bildschirmübergang mehr als 1 Sekunde dauern."

Dies beruht auch auf der Bereitstellung in einer produktionsähnlichen Testumgebung in Ihrer CI-Pipeline.

Es ist jedoch wahrscheinlich immer noch keine gute Idee, Leistungsanforderungen zu verwenden, um Ihre Entwicklung so zu steuern, wie Sie es mit funktionalen Anforderungen tun könnten. Bei den funktionalen Anforderungen haben Sie im Allgemeinen einen Einblick, ob Ihre Anwendung den Test besteht, bevor Sie sie ausführen, und es ist sinnvoll, Code zu schreiben, von dem Sie glauben, dass er ihn bestehen wird. Mit der Leistung versucht Code zu optimieren, dessen Leistung nicht funktioniert Gemessen wurde eine zweifelhafte Übung . Sie können performance results verwenden, um Ihre Anwendungsentwicklung in gewissem Umfang zu steuern, nur nicht performance -Anforderungen .

    
James_pic 23.11.2015 13:11
quelle