Home > OS >  Junit not running tests in parallel
Junit not running tests in parallel

Time:11-29

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.

  • Related