Ich habe eine Rails-Anwendung mit über 2.000 Beispielen in meinen RSpec-Tests. Es ist natürlich eine große Anwendung und es gibt viel zu testen. Das Ausführen dieser Tests zu diesem Zeitpunkt ist sehr ineffizient. Da dies so lange dauert, werden wir fast davon abgehalten, sie zu schreiben, bevor wir einen neuen Build veröffentlichen. Ich habe --profile zu meinen spec.opts hinzugefügt, um die am längsten laufenden Beispiele zu finden, und es gibt mindestens 10 davon, deren Ausführung durchschnittlich 10 Sekunden dauert. Ist das unter RSpec-Experten normal? Sind 10 Sekunden für ein Beispiel völlig zu lang? Mir ist klar, dass es bei 2.000 Beispielen nicht trivial sein wird, alles gründlich zu testen - aber an diesem Punkt sind 4 Stunden ein bisschen lächerlich.
Welche Zeiten sehen Sie für Ihre am längsten laufenden Beispiele? Was kann ich tun, um meine vorhandenen Spezifikationen zu beheben, um Engpässe herauszufinden und die Dinge zu beschleunigen? Jede Minute würde an dieser Stelle wirklich helfen.
quelle
perftools.rb
zusammen mit Ihrem Test-Framework, um zu verstehen, was die meiste Zeit Ihrer Zeit verbraucht. Nehmen Sie die Top 10 Anrufe an und versuchen Sie, sie zu eliminieren / zu überfliegen. Dann wiederhole, bis du glücklich bist.Antworten:
10 Sekunden sind eine sehr lange Zeit, um einen einzelnen Test auszuführen. Mein Bauchgefühl ist, dass Ihr Spezifikationsziel gleichzeitig Unit- und Integrationstests ausführt. Dies ist eine typische Sache, in die Projekte fallen, und irgendwann müssen Sie diese technische Verschuldung überwinden, wenn Sie mehr und schneller produzieren möchten. Es gibt eine Reihe von Strategien, die Ihnen dabei helfen können ... und ich werde einige empfehlen, die ich in der Vergangenheit verwendet habe.
1. Trennen Sie die Einheit von den Integrationstests
Das erste, was ich tun würde, ist, die Einheit von den Integrationstests zu trennen. Sie können dies entweder tun durch:
Die Philosophie besagt, dass Sie möchten, dass Ihre regulären Builds schnell sind - sonst sind die Leute nicht allzu glücklich, sie oft auszuführen. Also zurück in dieses Gebiet. Lassen Sie Ihre regelmäßigen Tests schnell laufen und verwenden Sie einen kontinuierlichen Integrationsserver, um den vollständigeren Build auszuführen.
Ein Integrationstest ist ein Test, der externe Abhängigkeiten beinhaltet (z. B. Datenbank, WebService, Warteschlange und einige würden FileSystem argumentieren). Ein Komponententest testet nur das spezifische Codeelement, das Sie überprüfen möchten. Es sollte schnell laufen (9000 in 45 Sekunden sind möglich), dh das meiste sollte im Speicher laufen.
2. Konvertieren Sie Integrationstests in Komponententests
Wenn der Großteil Ihrer Komponententests kleiner als Ihre Integrationstestsuite ist, liegt ein Problem vor. Dies bedeutet, dass Inkonsistenzen leichter auftreten. Erstellen Sie ab hier weitere Komponententests, um Integrationstests zu ersetzen. Sie können Folgendes tun, um diesen Prozess zu unterstützen:
Wenn Sie einen oder mehrere geeignete Komponententests zum Ersetzen eines Integrationstests haben, entfernen Sie den Integrationstest. Doppelte Tests verschlimmern die Wartung nur.
3. Verwenden Sie keine Geräte
Spielpaarungen sind böse. Verwenden Sie stattdessen eine Fabrik (Maschinist oder Factorybot). Diese Systeme können anpassungsfähigere Datengraphen erstellen und, was noch wichtiger ist, speicherinterne Objekte erstellen, die Sie verwenden können, anstatt Dinge aus einer externen Datenquelle zu laden.
4. Fügen Sie Überprüfungen hinzu, um zu verhindern, dass Komponententests zu Integrationstests werden
Jetzt, da Sie schnellere Tests durchgeführt haben, ist es Zeit, Überprüfungen durchzuführen, um zu verhindern, dass diese erneut auftreten.
Es gibt Bibliotheken, die Affen aktiv patchen, um einen Fehler auszulösen, wenn versucht wird, auf die Datenbank zuzugreifen (UnitRecord).
Sie können auch Pairing und TDD ausprobieren, um Ihr Team zu zwingen, schnellere Tests zu schreiben, weil:
5. Verwenden Sie andere Bibliotheken, um das Problem zu lösen
Jemand erwähnte Spork (beschleunigt die Ladezeiten für die Testsuite unter Rails3), hydra / parallel_tests - um Unit-Tests parallel (über mehrere Kerne hinweg) durchzuführen.
Dies sollte wahrscheinlich LETZT verwendet werden. Ihr eigentliches Problem ist in Schritt 1, 2, 3 zu lösen. Lösen Sie das Problem, und Sie sind besser in der Lage, zusätzliche Infrastrukturen auszurollen.
quelle
Ein großartiges Kochbuch zur Verbesserung der Leistung Ihrer Testsuite finden Sie in der Präsentation von Grease Your Suite .
Er dokumentiert eine 45-fache Beschleunigung der Laufzeit der Testsuite mithilfe von Techniken wie:
quelle
Sie können Spork verwenden. Es hat Unterstützung für 2.3.x,
https://github.com/sporkrb/spork
oder ./script/spec_server, der möglicherweise für 2.x funktioniert
Sie können auch die Datenbankkonfiguration bearbeiten (was die Datenbankabfragen usw. wesentlich beschleunigt), wodurch auch die Leistung für Tests erhöht wird.
quelle
10 Sekunden pro Beispiel scheinen eine sehr lange Zeit zu sein. Ich habe noch nie eine Spezifikation gesehen, die länger als eine Sekunde gedauert hat, und die meisten brauchen weit weniger. Testen Sie Netzwerkverbindungen? Datenbank schreibt? Dateisystem schreibt?
Verwenden Sie Mocks und Stubs so oft wie möglich - sie sind viel schneller als das Schreiben von Code, der in die Datenbank gelangt. Leider braucht das Verspotten und Stubben auch mehr Zeit zum Schreiben (und es ist schwieriger, es richtig zu machen). Sie müssen die Zeit, die Sie für das Schreiben von Tests aufgewendet haben, mit der Zeit abwägen, die Sie für das Ausführen von Tests aufgewendet haben.
Ich stimme Andrew Grimms Kommentar über die Untersuchung eines CI-Systems zu, mit dem Sie möglicherweise Ihre Testsuite parallelisieren können. Für etwas dieser Größe könnte es die einzig praktikable Lösung sein.
quelle
Einige Leute haben Hydra oben erwähnt. Wir haben es in der Vergangenheit mit großem Erfolg eingesetzt. Ich habe kürzlich den Prozess der Inbetriebnahme von Hydra dokumentiert: http://logicalfriday.com/2011/05/18/faster-rails-tests-with-hydra/
Ich stimme dem Gefühl zu, dass diese Art von Technik nicht als Ersatz für das Schreiben von Tests verwendet werden sollte, die standardmäßig gut strukturiert und schnell sind.
quelle
Wenn Sie ActiveRecord-Modelle verwenden, sollten Sie auch die Kosten für die BCrypt-Verschlüsselung berücksichtigen.
Sie können mehr darüber in diesem Blog-Beitrag lesen: http://blog.syncopelabs.co.uk/2012/12/speed-up-rspec-test.html
quelle
schneller_require gem könnte dir helfen. Außerdem besteht Ihre einzige Möglichkeit darin, (wie Sie) ein Profil zu erstellen und zu optimieren oder Spork oder etwas zu verwenden, das Ihre Spezifikationen für Sie parallel ausführt. http://ruby-toolbox.com/categories/distributed_testing.html
quelle
Sie können ein paar einfache Tipps befolgen, um zunächst zu untersuchen, wo die meiste Zeit verbracht wird, wenn Sie sie noch nicht ausprobiert haben. Schauen Sie sich den Artikel unten an:
https://blog.mavenhive.in/7-tips-to-speed-up-your-webdriver-tests-4f4d043ad581
Ich denke, die meisten davon sind generische Schritte, die unabhängig vom zu testenden Tool gelten.
quelle
Löschen Sie die vorhandene Testsuite. Wird unglaublich effektiv sein.
quelle