I have test:
import org.junit.jupiter.api.parallel.Execution // version 5.9.0
import org.junit.jupiter.api.parallel.ExecutionMode
import spock.lang.Specification
import spock.lang.Unroll
@Execution(ExecutionMode.CONCURRENT)
class ExampleTest extends Specification {
@Unroll
@Execution(ExecutionMode.CONCURRENT)
def "test1: should get valid #testParam"() {
System.out.println("FirstParallelUnitTest first() start => " Thread.currentThread().getName()
" id: " Thread.currentThread().getId());
given:
def test = testParam
expect:
test != null
System.out.println("FirstParallelUnitTest first() end => " Thread.currentThread().getName()
" id: " Thread.currentThread().getId());
where:
testParam << ["one", "two", "three", "four"]
}
@Unroll
@Execution(ExecutionMode.CONCURRENT)
def "test2: should get valid #testParam"() {
System.out.println("FirstParallelUnitTest first() start => " Thread.currentThread().getName()
" id: " Thread.currentThread().getId());
given:
def test = testParam
expect:
test != null
System.out.println("FirstParallelUnitTest first() end => " Thread.currentThread().getName()
" id: " Thread.currentThread().getId());
where:
testParam << ["one", "two", "three", "four"]
}
@Unroll
@Execution(ExecutionMode.CONCURRENT)
def "test3: should get valid #testParam"() {
System.out.println("FirstParallelUnitTest first() start => " Thread.currentThread().getName()
" id: " Thread.currentThread().getId());
given:
def test = testParam
expect:
test != null
System.out.println("FirstParallelUnitTest first() end => " Thread.currentThread().getName()
" id: " Thread.currentThread().getId());
where:
testParam << ["one", "two", "three", "four"]
}
}
I have created junit-platform.properties
file in src/test/resources
that contains:
junit.jupiter.execution.parallel.enabled=true
junit.jupiter.execution.parallel.mode.default = concurrent
junit.jupiter.execution.parallel.mode.classes.default = concurrent
junit.jupiter.execution.parallel.config.strategy=fixed
junit.jupiter.execution.parallel.config.fixed.parallelism=2
I have also tried adding systemProperties
like that in gradle
file:
test {
testLogging {
exceptionFormat = 'full'
}
useJUnitPlatform()
systemProperties([
'junit.jupiter.execution.parallel.enabled': 'true',
'junit.jupiter.execution.parallel.mode.default': 'concurrent',
'junit.jupiter.execution.parallel.mode.classes.default': 'concurrent',
])
}
I am using gradle
version 7.6
.
I added this junit
test dependencies:
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
testImplementation("org.junit.jupiter:junit-jupiter-params")
I have also tried adding to build.gradle
this:
subprojects {
tasks.withType(Test) {
maxParallelForks = Runtime.runtime.availableProcessors()
}
}
Not divided cause i wanted to see change on i7-6600U
processor (2 cores).
When running the test i see these logs:
FirstParallelUnitTest first() start => Test worker id: 1
FirstParallelUnitTest first() end => Test worker id: 1
FirstParallelUnitTest first() start => Test worker id: 1
FirstParallelUnitTest first() end => Test worker id: 1
FirstParallelUnitTest first() start => Test worker id: 1
FirstParallelUnitTest first() end => Test worker id: 1
FirstParallelUnitTest first() start => Test worker id: 1
FirstParallelUnitTest first() end => Test worker id: 1
FirstParallelUnitTest first() start => Test worker id: 1
FirstParallelUnitTest first() end => Test worker id: 1
FirstParallelUnitTest first() start => Test worker id: 1
FirstParallelUnitTest first() end => Test worker id: 1
FirstParallelUnitTest first() start => Test worker id: 1
FirstParallelUnitTest first() end => Test worker id: 1
FirstParallelUnitTest first() start => Test worker id: 1
FirstParallelUnitTest first() end => Test worker id: 1
FirstParallelUnitTest first() start => Test worker id: 1
FirstParallelUnitTest first() end => Test worker id: 1
FirstParallelUnitTest first() start => Test worker id: 1
FirstParallelUnitTest first() end => Test worker id: 1
FirstParallelUnitTest first() start => Test worker id: 1
FirstParallelUnitTest first() end => Test worker id: 1
FirstParallelUnitTest first() start => Test worker id: 1
FirstParallelUnitTest first() end => Test worker id: 1
thread
id
does not change, or the order of start/end
does not change each time.
How can I run this test in parallel and each other test in parallel ?
CodePudding user response:
You should use @spock.lang.Execution
and org.spockframework.runtime.model.parallel.ExecutionMode
annotations/classes instead of JUnit 5 ones. As an example, your imports might look like this:
import org.spockframework.runtime.model.parallel.ExecutionMode
import spock.lang.Execution
import spock.lang.Specification
import spock.lang.Unroll
You should also enable the "Parallel Execution" feature in Spock, e.g. by adding SpockConfig.groovy with necessary configs (different options are available, just refer to that page). As an example, your config might look like this:
runner {
parallel {
enabled true
}
}
I've put this file into the test resources directory (root package). Also, read a note on that page which states:
JUnit Jupiter also supports parallel execution, both rely on the JUnit Platform implementation, but function independently of each other. If you enable parallel execution in Spock it won’t affect Jupiter and vice versa.
An in general, that "Parallel Execution" article is a good read.
Once I've done the above I'm able to run the test methods in parallel. Here is my output:
FirstParallelUnitTest first() start => ForkJoinPool-1-worker-1 id: 17
FirstParallelUnitTest first() start => ForkJoinPool-1-worker-6 id: 22
FirstParallelUnitTest first() start => ForkJoinPool-1-worker-5 id: 20
FirstParallelUnitTest first() end => ForkJoinPool-1-worker-6 id: 22
FirstParallelUnitTest first() end => ForkJoinPool-1-worker-1 id: 17
FirstParallelUnitTest first() end => ForkJoinPool-1-worker-5 id: 20
FirstParallelUnitTest first() start => ForkJoinPool-1-worker-4 id: 21
FirstParallelUnitTest first() start => ForkJoinPool-1-worker-2 id: 18
FirstParallelUnitTest first() end => ForkJoinPool-1-worker-2 id: 18
FirstParallelUnitTest first() end => ForkJoinPool-1-worker-4 id: 21
FirstParallelUnitTest first() start => ForkJoinPool-1-worker-1 id: 17
FirstParallelUnitTest first() start => ForkJoinPool-1-worker-6 id: 22
FirstParallelUnitTest first() start => ForkJoinPool-1-worker-2 id: 18
FirstParallelUnitTest first() start => ForkJoinPool-1-worker-5 id: 20
FirstParallelUnitTest first() start => ForkJoinPool-1-worker-3 id: 19
FirstParallelUnitTest first() end => ForkJoinPool-1-worker-6 id: 22
FirstParallelUnitTest first() end => ForkJoinPool-1-worker-3 id: 19
FirstParallelUnitTest first() end => ForkJoinPool-1-worker-2 id: 18
FirstParallelUnitTest first() end => ForkJoinPool-1-worker-5 id: 20
FirstParallelUnitTest first() end => ForkJoinPool-1-worker-1 id: 17
FirstParallelUnitTest first() start => ForkJoinPool-1-worker-4 id: 21
FirstParallelUnitTest first() end => ForkJoinPool-1-worker-4 id: 21
FirstParallelUnitTest first() start => ForkJoinPool-1-worker-2 id: 18
FirstParallelUnitTest first() end => ForkJoinPool-1-worker-2 id: 18
Without those steps my output was sequential as yours.