Le code suivant devrait atteindre vos exigences, qui a été prise à partir du livre allemand JUnit Profiwissen qui contient quelques conseils pour soit des tests, des trucs en parallèle ou sur la façon de réduire le temps d'exécution par le biais de l'utilisation de plusieurs cœurs au lieu d'un seul cœur.
JUnit 4.6 introduit un ParallelComputer classe qui a offert l'exécution en parallèle de tests. Toutefois, cette fonctionnalité n'était pas accessible au public jusqu'à ce que JUnit 4.7 qui donnent la possibilité de personnaliser le planificateur pour le parent coureur.
public class ParallelScheduler implements RunnerScheduler {
private ExecutorService threadPool = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors());
@Override
public void schedule(Runnable childStatement) {
threadPool.submit(childStatement);
}
@Override
public void finished() {
try {
threadPool.shutdown();
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Got interrupted", e);
}
}
}
public class ParallelRunner extends BlockJUnit4ClassRunner {
public ParallelRunner(Class<?> klass) throws InitializationError {
super(klass);
setScheduler(new ParallelScheduler());
}
}
Maintenant, si vous annoter un test de classe avec @RunWith(ParallelRunner.class)
chaque méthode fonctionne dans son propre thread. En outre, il y aura autant de threads actifs (seulement) comme CPU-cores sont disponibles à l'exécution de la machine.
Si plusieurs classes doivent être exécutées en parallèle, vous pouvez définir une mesure de la suite comme ceci:
public class ParallelSuite extends Suite {
public ParallelSuite(Class<?> klass, RunnerBuilder builder)
throws InitializationError {
super(klass, builder);
setScheduler(new ParallelScheduler());
}
}
et puis le changement @RunWith(Suite.class)
avec @RunWith(ParallelSuite.class)
Vous pouvez même tirer parti de la fonctionnalité de f.e. l' WildcardPatternSuite
en étendant directement à partir de la suite au lieu de Suite
comme dans l'exemple de l'avant. Cela vous permet en outre à l'unité de filtre-tests f.e. par tout @Category
- une suite de tests qui n'exécute UnitTest
annoté catégories en parallèle, pourrait ressembler à ceci:
public interface UnitTest {
}
@RunWith(ParallelSuite.class)
@SuiteClasses("**/*Test.class")
@IncludeCategories(UnitTest.class)
public class UnitTestSuite {
}
Un simple cas de test pourrait ressembler à ceci:
@Category(UnitTest.class)
@RunWith(MockitoJUnitRunner.class)
public class SomeClassTest {
@Test
public void testSomething() {
...
}
}
L' UnitTestSuite
seront exécutées à chaque classe a trouvé en subdirecotries qui se termine par Test
et a un @Category(UnitTest.class)
spécifié en parallèle en fonction du nombre de cœurs de PROCESSEUR disponibles.
Je ne sais pas si il peut faire plus simple que ça :)