Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ The JUnit Toolbox provides some useful classes for writing automated tests with
* [WildcardPatternSuite](//michaeltamm.github.io/junit-toolbox/com/googlecode/junittoolbox/WildcardPatternSuite.html) -- A replacement for the JUnit runners `Suite` and `Categories`, which allows you to specify the children classes of your test suite class using a wildcard pattern. Furthermore you can include and/or exclude multiple categories.
* [ParallelSuite](//michaeltamm.github.io/junit-toolbox/com/googlecode/junittoolbox/ParallelSuite.html) -- An extension of the `WildcardPatternSuite`, which executes its children classes concurrently using several worker threads. Although it extends `WildcardPatternSuite` you are not forced to use a wildcard pattern, you can also list the children class using the `@SuiteClasses` annotation known from JUnit.
* [InnerTestClassesSuite](//michaeltamm.github.io/junit-toolbox/com/googlecode/junittoolbox/InnerTestClassesSuite.html) -- A replacement for the JUnit runner `Enclosed` which executes all inner test classes of the class annotated with ` @RunWith(InnerTestClassesSuite.class)`. In contrast to the `Enclosed` runner provided by JUnit it detects if an inner class is actually a test class and ignores all other inner classes.
* [ParallelInnerTestClassesSuite](//michaeltamm.github.io/junit-toolbox/com/googlecode/junittoolbox/ParallelInnerTestClassesSuite.html) -- A replacement for `InnerTestClassesSuite` which executes its children classes concurrently using several worker threads.

`ParallelRunner`, `ParallelParameterized`, and `ParallelSuite` share a common Fork-Join-Pool. You can control the maximum number of worker threads by specifying the system property `maxParallelTestThreads`. If this system property is not set, there will be as many worker threads as the number of processors available to the JVM.
`ParallelRunner`, `ParallelParameterized`, `ParallelSuite` and `ParallelInnerTestClassesSuite` share a common Fork-Join-Pool. You can control the maximum number of worker threads by specifying the system property `maxParallelTestThreads`. If this system property is not set, there will be as many worker threads as the number of processors available to the JVM.

# How to use it #

Expand All @@ -18,12 +19,36 @@ If you use [Maven](http://maven.apache.org), add the following dependency to you
<dependency>
<groupId>com.googlecode.junit-toolbox</groupId>
<artifactId>junit-toolbox</artifactId>
<version>2.4</version>
<version>2.5</version>
</dependency>
```

# Release Notes #

## Version 2.5 (for Java 8) and Version 1.12 (for Java 6) ##

* New runner `ParallelInnerTestClassesSuite` which runs all inner test classes of the class annotated with `@RunWith(ParallelInnerTestClassesSuite.class)`. In contrast to the `Enclosed` runner provided by JUnit, it detects if an inner class is actually a test class and ignores all other inner classes. In contrast to `InnerTestClassesSuite` it executes its children classes concurrently using several worker threads. run Example:
```
@RunWith(ParallelInnerTestClassesSuite.class)
public class LoginBeanTests {

public static class UnitTests {
@Test
public void test1() { ... }
}

@Configuration
public static class IntegrationTestsConfig { ... }

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = IntegrationTestsConfig.class)
public static class IntegrationTests {
@Test
public void test2() { ... }
}
}
```

## Version 2.4 (for Java 8) and Version 1.11 (for Java 6) ##
* [WildcardPatternSuite](//michaeltamm.github.io/junit-toolbox/com/googlecode/junittoolbox/WildcardPatternSuite.html) can now handle wildcard patterns starting with "../" (fixes [#16](https://github.com/MichaelTamm/junit-toolbox/issues/16))
* Fixed edge case where too many threads were created when using one of [ParallelRunner](//michaeltamm.github.io/junit-toolbox/com/googlecode/junittoolbox/ParallelRunner.html), [ParallelParameterized](//michaeltamm.github.io/junit-toolbox/com/googlecode/junittoolbox/ParallelParameterized.html), or [ParallelSuite](//michaeltamm.github.io/junit-toolbox/com/googlecode/junittoolbox/ParallelSuite.html) contributed by Till Klister
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.googlecode.junittoolbox;

import org.junit.experimental.runners.Enclosed;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerBuilder;

/**
* Runs all inner test classes of the class
* annotated with <code>&#64;RunWith(ParallelInnerTestClassesSuite&#46;class)</code>.
* It executes its children classes concurrently. You can specify the maximum number
* of parallel test threads using the system property <code>maxParallelTestThreads</code>.
* If this system property is not specified, the maximum number of test threads
* will be the number of {@link Runtime#availableProcessors() available processors.}
* In contrast to the {@link Enclosed} runner provided by
* <a href="http://junit.org/" target="_blank">JUnit</a>,
* it detects if an inner class is actually a test class
* and ignores all other inner classes.
* Example:<pre>
* &#64;RunWith(ParallelInnerTestClassesSuite.class)
* public class LoginBeanTests {
*
* public static class UnitTests {
* &#64;Test
* public void test1() { ... }
* }
*
* &#64;Configuration
* public static class IntegrationTestsConfig { ... }
*
* &#64;RunWith(SpringJUnit4ClassRunner.class)
* &#64;ContextConfiguration(classes = IntegrationTestsConfig.class)
* public static class IntegrationTests {
* &#64;Test
* public void test2() { ... }
* }
* }
* </pre>
*/
public class ParallelInnerTestClassesSuite extends InnerTestClassesSuite {
public ParallelInnerTestClassesSuite(Class<?> klass, RunnerBuilder runnerBuilder) throws InitializationError {
super(klass, runnerBuilder);
setScheduler(new ParallelScheduler());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package com.googlecode.junittoolbox;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.*;

public class ParallelInnerTestClassesSuiteTest {

private static volatile CountDownLatch latch;
private static volatile Thread thread1 = null;
private static volatile Thread thread2 = null;

@Before
public void setUp() {
latch = new CountDownLatch(2);
}

@RunWith(ParallelInnerTestClassesSuite.class)
@SuiteClasses({})
public static class EmptyExample{}

@Test
public void test_empty_ParallelSuite() {
Result result = JUnitCore.runClasses(EmptyExample.class);
assertTrue(result.wasSuccessful());
assertEquals(0, result.getRunCount());
}

@RunWith(ParallelInnerTestClassesSuite.class)
public static class Example1 {
public static class Test1 {
@Test
public void test() throws InterruptedException {
latch.countDown();
assertTrue(latch.await(3, TimeUnit.SECONDS));
thread1 = Thread.currentThread();
}
}

public static class Test2 {
@Test
public void test() throws InterruptedException {
latch.countDown();
assertTrue(latch.await(3, TimeUnit.SECONDS));
thread2 = Thread.currentThread();
}
}
}

@Test
public void test() {
Result result = JUnitCore.runClasses(Example1.class);
assertTrue(result.wasSuccessful());
assertEquals(2, result.getRunCount());
assertNotNull(thread1);
assertNotNull(thread2);
assertNotSame(thread1, thread2);
}

@RunWith(ParallelInnerTestClassesSuite.class)
public static class Example2 {
public static class Test1 extends Example1.Test1 {}
public static class Test2 extends Example1.Test2 {}
public static class ParallelRunnerTest_ extends ParallelRunnerTest.Example {}
}

@Test
public void test_with_child_using_ParallelRunner() {
Result result = JUnitCore.runClasses(Example2.class);
assertTrue(result.wasSuccessful());
assertEquals(4, result.getRunCount());
assertNotSame(ParallelRunnerTest.Example.thread1, ParallelRunnerTest.Example.thread2);
}

@RunWith(ParallelInnerTestClassesSuite.class)
public static class Example3 {
public static class Example1_ extends Example1 {}
public static class Example2_ extends Example2 {}
}

@Test
public void test_nested_ParallelSuites() {
Result result = JUnitCore.runClasses(Example3.class);
assertTrue(result.wasSuccessful());
assertEquals(6, result.getRunCount());
}
}