2008-10-21 8 views
7

Ich habe einen Java-Dienst, der jetzt im Batch-Modus ausgeführt wird. Multi-Threading-Unterstützung wird dem Dienst hinzugefügt, sodass für jede Stapelanforderung ein Thread-Pool zum Ausführen des Stapels bereitgestellt wird. Die Frage ist, wie kann ich das testen? Ich habe Funktionstests, die unter der Threaded-Version des Dienstes gehen, aber irgendwie, ich denke, dass es ein Idiom geben muss, um das zu testen.Wie fügen Sie Tests für Multi-Thread-Unterstützung hinzu?

Antwort

6

Es gibt wirklich keinen "guten" Weg, dies zu tun. Das beste, was ich vorschlagen kann, wäre TestNG, mit dem Sie Ihre Testmethoden mit Anmerkungen versehen und sie in n Threads gleichzeitig ausführen können. Zum Beispiel:

@Test(invocationCount=10, threadPool=10) 
public void testSomethingConcurrently() { 
    ... 
} 

Mein TestNG Wissen ist besten rostig, aber AFAIK das sollte die testSomethingConcurrently Methode 10mal gleichzeitig aufrufen. Dies ist eine nette und deklarative Möglichkeit, Multi-Threading-Tests gegen Ihren Code durchzuführen.

Sie können natürlich in JUnit etwas ähnliches tun, indem Sie Threads manuell in einer Schleife erzeugen, aber das ist wahnsinnig hässlich und schwer zu bearbeiten. Ich musste das für ein Projekt, an dem ich arbeitete, einmal machen; Diese Tests waren ein Alptraum, da ihre Fehler nicht immer wiederholbar waren.

Concurrency-Tests sind aufgrund ihrer nicht-deterministischen Natur schwierig und anfällig für Frustration. Dies ist einer der Gründe, warum es heute so einen großen Drang gibt, bessere Nebenläufigkeits-Abstraktionen zu verwenden, die leichter "vernünftig" zu argumentieren sind und sich selbst von der Korrektheit überzeugen.

0

Ich stimme mit Daniel überein, Nebenläufigkeitstests sind in der Tat sehr schwierig.

Ich habe keine Lösung für Parallelitätstests, aber ich werde Ihnen sagen, was ich mache, wenn ich Code testen möchte, der Multithreading beinhaltet. Die meisten meiner Tests werden mit JUnit und JMock durchgeführt. Da JMock mit mehreren Threads nicht gut funktioniert, verwende ich eine Erweiterung von JMock, die synchrone Versionen von Executor und ScheduledExecutorService bereitstellt. Dadurch kann ich Code testen, der von mehreren Threads in einem einzigen Thread ausgeführt wird, wobei ich auch den Ausführungsfluss steuern kann. Wie ich bereits gesagt habe, testet dies die Nebenläufigkeit nicht. Es überprüft nur das Verhalten meines Codes auf eine einzige Art und Weise, aber es reduziert die Anzahl der Fehler, die ich erhalte, wenn ich zu den Multithread-Executoren wechsle.

Wie auch immer ich empfehle die Verwendung der neuen Java Concurrency API. Es macht die Dinge viel einfacher.

1

Normalerweise sind die Dinge, die Multithread-Anwendungen zum Absturz bringen, Timing-Probleme. Ich vermute, dass das Ausführen von Komponententests für die gesamte Multithread-Umgebung große Änderungen an der Codebasis erfordern würde.

Was Sie möglicherweise tun können, ist jedoch, die Implementierung des Thread-Pools isoliert zu testen.

Indem Sie den Körper der Threads mit Testcode ersetzen, sollten Sie in der Lage sein, Ihre pathologischen Bedingungen für die Sperrung und Ressourcennutzung zu konstruieren.

Testen Sie dann die Funktionselemente in einer Umgebung mit einem einzelnen Thread, in der Sie das Timing ignorieren können.

Obwohl dies nicht perfekt ist, garantiert es doch die Wiederholbarkeit, die für Ihre Gerätetests von großer Bedeutung ist.(Wie in Daniel Spiewak Antwort angedeutet)

1

I verwendet

@Test(threadPoolSize = 100, invocationCount = 100) 
    @DataProvider(parallel = true) 

100 Threads parallel 100-mal ausgeführt.

Verwandte Themen