2013-05-07 12 views
7

Ich habe eine Sammlung von Integrationstests mit SpringJUnit4ClassRunner ausgeführt. Ich versuche, diese parallel mit Maven todsichere laufen. Ich habe jedoch festgestellt, dass der Code blockiert, bevor Sie den synchronisierten Block in CacheAwareContextLoaderDelegate.loadContext() eingeben.Laufende Federtests parallel zu maven

Gibt es eine Möglichkeit, diesen Cache zu umgehen? Ich habe versucht, dies zu tun, aber es scheint, dass es mehr freigegebenen Zustand gibt als nur den Cache selbst seit meiner Anwendung im Spring-Code festgefahren. Oder könnte die Synchronisation feinkörniger gestaltet werden, indem irgendwie auf dem Kartenschlüssel anstatt auf der gesamten Karte synchronisiert wird?

für Meine Motivation Tests Parallelisierung ist zweifach:

  1. In einigen Tests ich ersetzen Bohnen mit Mocks. Da Mocks inhärent statusbehaftet sind, muss ich für jede Testmethode einen neuen ApplicationContext erstellen, der @DirtiesContext verwendet.
  2. In anderen Tests möchte ich nur eine Teilmenge von Jersey-Ressourcen bereitstellen. Zu diesem Zweck gebe ich eine Teilmenge der Spring-Konfigurationsklassen an. Da Spring das MergedContextConfiguration als einen Schlüssel in dem Kontextcache verwendet, können diese Tests ApplicationContexts nicht freigeben.
+0

Ich habe [einen Fehlerbericht dafür erstellt] (https: //jira.springsource.org/browse/SPR-10536) – hertzsprung

Antwort

3

Es ist möglich, dass eine bessere Turn-around für Ihren Test Anzug Zeit erhalten können, wenn Sie die parallell Testausführung deaktivieren. Bei der Prüfung Kapitel der Referenz docs Frühling gibt es einen Absatz über Context caching:

Sobald der Testcontext Rahmen eines Application (oder WebApplicationContext) für einen Test lädt, wird dieser Kontext im Cache gespeichert und für alle nachfolgenden Tests wiederverwendet werden, die erklären dieselbe einzigartige Kontextkonfiguration innerhalb derselben Testsuite.

Warum wird es so implementiert?

Dies bedeutet, dass die Installationskosten für das Laden eines Anwendungskontextes nur einmal (pro Testsuite) anfallen und die nachfolgende Testausführung viel schneller ist.

Wie funktioniert der Cache?

Das Spring TestContext-Framework speichert Anwendungskontexte in einem statischen Cache. Dies bedeutet, dass der Kontext in einer statischen Variablen gespeichert wird. Mit anderen Worten, wenn Tests in separaten Prozessen ausgeführt werden, wird der statische Cache zwischen jeder Testausführung gelöscht, wodurch der Caching-Mechanismus effektiv deaktiviert wird.

Um vom Caching-Mechanismus zu profitieren, müssen alle Tests innerhalb desselben Prozesses oder derselben Testsuite ausgeführt werden. Dies kann erreicht werden, indem alle Tests als Gruppe innerhalb einer IDE ausgeführt werden. Ebenso ist es wichtig, beim Ausführen von Tests mit einem Build-Framework wie Ant, Maven oder Gradle sicherzustellen, dass das Build-Framework zwischen den Tests nicht verzweigt. Wenn beispielsweise der forkMode für das Maven Surefire-Plug-in auf "Immer" festgelegt ist, kann das TestContext-Framework Anwendungskontexte zwischen Testklassen nicht zwischenspeichern und der Buildprozess wird dadurch erheblich langsamer ausgeführt.

+0

Danke, ich glaube nicht, dass ich diesen Absatz in der Dokumentation gelesen habe. Ich habe meine Frage aktualisiert, um meine Motivation zur Parallelisierung zu erklären. Hoffentlich [der Fehler, den ich gemeldet habe] (https://jira.springsource.org/browse/SPR-10536) wird bald behoben. – hertzsprung

+1

@hertzsprung Ich schlage vor, dass Sie einen separaten Scheinanwendungskontext erstellen (oder einen Test [Profil] (http://blog.springsource.com/2011/02/14/spring-3-1-m1-introducing-profile/) (enthält die Mocks), die zwischengespeichert und durch andere Tests wiederverwendet werden können (das ist möglich, wenn Sie den Status des Mocked - Objekts zurücksetzen, zB in '@ Before' oder' @ After'. Lesen kann weitere Informationen finden in mein [Blogbeitrag] (http://www.jayway.com/2011/12/12/spring-integration-tests-part-ii-using-mock-objects/)). – matsev

0

Eine einfache Sache, die ich @DirtiesContext von nutzt einfiel

+1

Danke, mir ist diese Anmerkung bekannt. Es kann den Kontext zwischen Testklassen oder Testmethoden löschen, vermeidet aber die globale Sperre meines Wissens nicht. – hertzsprung

+0

Genau, meiner Meinung nach sollte @DirtiesContext als Anti-Pattern behandelt werden. –