2008-10-21 6 views
7

J'ai un service Java qui va maintenant s'exécuter en mode batch. Le support multithread est ajouté au service, de sorte que pour chaque requête par lot, un pool de threads sera dédié à l'exécution du batch. La question est comment puis-je tester cela? J'ai des tests fonctionnels qui passent sous la version filetée du service mais, d'une manière ou d'une autre, je pense qu'il doit y avoir un idiome pour tester cela.Comment ajouter des tests pour un support multi-thread?

Répondre

6

Il n'y a vraiment pas de "bon" moyen de le faire. La meilleure chose que je peux suggérer serait TestNG, qui vous permet d'annoter vos méthodes de test et de les faire exécuter en n threads simultanément. Par exemple:

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

Ma connaissance testng est rouillé au mieux, mais autant que je sache que doit appeler la méthode testSomethingConcurrently 10 fois simultanément. C'est une façon agréable et déclarative d'exécuter des tests multithread avec votre code.

Vous pouvez bien sûr faire quelque chose de similaire dans JUnit en engendrant des fils manuellement dans une boucle, mais c'est incroyablement moche et difficile à travailler. Je devais le faire une fois pour un projet sur lequel je travaillais; ces tests étaient un cauchemar à gérer car leurs échecs n'étaient pas toujours reproductibles.

Les tests de simultanéité sont difficiles et sujets à la frustration, en raison de leur nature non déterministe. Cela fait partie de la raison pour laquelle il y a une telle poussée ces jours-ci pour utiliser de meilleures abstractions d'accès simultanées, qui sont plus faciles à «raisonner» et à se convaincre de la justesse.

0

Je suis d'accord avec Daniel, les tests de simultanéité sont en effet très difficiles.

Je n'ai pas de solution pour les tests de simultanéité, mais je vais vous dire ce que je fais quand je veux tester le code impliquant le multi-threading. La plupart de mes tests sont effectués en utilisant JUnit et JMock. Puisque JMock ne fonctionne pas bien avec plusieurs threads, j'utilise une extension de JMock qui fournit des versions synchrones de Executor et ScheduledExecutorService. Ceux-ci me permettent de tester le code ciblé pour être exécuté par plusieurs threads dans un seul thread, où je suis également capable de contrôler le flux d'exécution. Comme je l'ai déjà dit, cela ne teste pas la concurrence. Il vérifie uniquement le comportement de mon code d'une seule manière, mais il réduit le nombre d'erreurs que j'obtiens lorsque je passe aux exécuteurs multi-threads.

Quoi qu'il en soit, je recommande l'utilisation de la nouvelle API de concurrence Java. Cela rend les choses beaucoup plus faciles.

1

Habituellement, les choses qui font baisser les applications multithread sont des problèmes de timing. Je soupçonne que pour être en mesure d'effectuer des tests unitaires sur l'environnement multithread complet nécessiterait d'énormes changements à la base de code pour le faire.

Cependant, vous pouvez tester l'implémentation du pool de threads de manière isolée. En remplaçant le corps des threads par le code de test, vous devriez être capable de construire vos conditions pathologiques de verrouillage et d'utilisation des ressources.

Ensuite, l'unité tester les éléments fonctionnels dans un environnement à un seul thread, où vous pouvez ignorer la synchronisation.

Bien que ce ne soit pas parfait, il garantit une répétabilité qui est d'une grande importance pour vos tests unitaires.(Comme évoqué dans la réponse de Daniel Spiewak)

1

J'utilisé

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

exécuté 100 fils en 100 fois parallèles.

Questions connexes