RSpec durch Parallelisierung beschleunigen

Mit der testgetriebenen Entwicklung gibt es vor allem ein großes Problem:

Finished in 2 minutes 32.8 seconds
547 examples, 0 failures, 4 pending

Schon in einem frühen Stadium läuft die Testsuite locker zwei Minuten. Parallel Tests will die Dauer verkürzen, indem es Tests auf mehreren Prozessorkernen gleichzeitig ausführt.

Ein wesentlicher Aspekt bei der Parallelisierung ist der gleichzeitige Zugriff unterschiedlicher Prozesse auf eine Datenbank. Das Gem behebt die auftretenden Konflikte, indem es jedem Prozess seine eigene Datenbank zuweist. Die Anzahl der Prozesse richtet sich dabei nach den verfügbaren Kernen.

Einrichtung

Gemfile:

group :development do
  # ...
  gem 'parallel_tests'
end

config/database.yml:

test: &test
  database: myapp-test<%= ENV['TEST_ENV_NUMBER'] %>
bundle
rake parallel:create

Der Task beschwert sich, das eine der Datenbanken bereits existiert. Dies ist jedoch nur ein Hinweis, die Duplikate werden wie gewünscht erzeugt.

Schemastand anpassen

Nach der Einrichtung und nach jeder Migration müssen die Schemata der Datenbanken angeglichen werden. Auch hierfür liefert das Gem den passenden Task:

rake parallel:prepare

Mit vier Kernen die Zeit halbieren

Das Ergebnis ist in meinem Beispielfall recht beeindruckend. Die parallelisierte Variante benötigt nicht einmal die Hälfte der Zeit:

rake parallel:spec
547 examples, 0 failures, 4 pendings
Took 67.945901274 seconds

Problematisch ist in dieser Konfiguration die Ausgabe: Alle Prozesse schreiben gleichzeitig ins Terminal, was jede RSpec-Visualisierung zerschießt. Die auf der Github-Seite vorgeschlagenen Logger brachten entweder keine Besserung oder führten dazu, dass Fehlermeldungen gar nicht mehr angezeigt wurden.

Zeus- und Guard-Unterstützung

Wer seine Tests nicht immer selbst auslösen will und auf die zehn Sekunden Wartezeit für die Rails-Umgebung verzichten kann, sollte sich dieses Gem ansehen, welches die drei Komponenten Guard, Zeus und Parallel Tests zusammenschraubt.