Skip to content

Latest commit

 

History

History
235 lines (171 loc) · 6.04 KB

File metadata and controls

235 lines (171 loc) · 6.04 KB

Introduction to parallel execution in Spock

In this part you will learn and exercise parallel execution feature for Spock.

First, familiarize yourself with tests in this module.

No parallelization

  • Run tests ./gradlew --rerun-tasks :part1.0-introduction:test :part1.0-introduction:createTestsExecutionReport
  • Check reports

Parallel execution

runner {
    parallel {
        enabled true
    }
}
  • Run tests ./gradlew --rerun-tasks :part1.0-introduction:test :part1.0-introduction:createTestsExecutionReport
  • Check reports

Check other reports created by Gradle:

Execution modes

  • two execution modes
    • SAME_THREAD
    • CONCURRENT
  • defined
    • for specifications (test classes) by runner.parallel.defaultSpecificationExecutionMode
    • for features (tests methods) by runner.parallel.defaultExecutionMode

Sample configuration:

import org.spockframework.runtime.model.parallel.ExecutionMode

runner {
    parallel {
        enabled true
        defaultSpecificationExecutionMode ExecutionMode.SAME_THREAD
        defaultExecutionMode ExecutionMode.SAME_THREAD
    }
}

Sequential Execution (SAME_THREAD Specifications, SAME_THREAD Features)

diagram

  • Set
runner {
    parallel {
        enabled false
    }
}
  • or
import org.spockframework.runtime.model.parallel.ExecutionMode

runner {
    parallel {
        enabled true
        defaultSpecificationExecutionMode ExecutionMode.SAME_THREAD
        defaultExecutionMode ExecutionMode.SAME_THREAD
    }
}
  • Run tests ./gradlew --rerun-tasks :part1.0-introduction:test :part1.0-introduction:createTestsExecutionReport
  • Check reports

CONCURRENT Specifications, CONCURRENT Features

diagram

  • Set
import org.spockframework.runtime.model.parallel.ExecutionMode

runner {
    parallel {
        enabled true
    }
}
  • or
import org.spockframework.runtime.model.parallel.ExecutionMode

runner {
    parallel {
        enabled true
        // ExecutionMode.CONCURRENT is a default value
        // of defaultSpecificationExecutionMode and defaultExecutionMode
        defaultSpecificationExecutionMode ExecutionMode.CONCURRENT
        defaultExecutionMode ExecutionMode.CONCURRENT
    }
}
  • Run tests ./gradlew --rerun-tasks :part1.0-introduction:test :part1.0-introduction:createTestsExecutionReport
  • Check reports

CONCURRENT Specifications, SAME_THREAD Features

diagram

  • Set
import org.spockframework.runtime.model.parallel.ExecutionMode

runner {
    parallel {
        enabled true
        defaultSpecificationExecutionMode ExecutionMode.CONCURRENT
        defaultExecutionMode ExecutionMode.SAME_THREAD
    }
}
  • Run tests ./gradlew --rerun-tasks :part1.0-introduction:test :part1.0-introduction:createTestsExecutionReport
  • Check reports

SAME_THREAD Specifications, CONCURRENT Features

diagram

  • Set
import org.spockframework.runtime.model.parallel.ExecutionMode

runner {
    parallel {
        enabled true
        defaultSpecificationExecutionMode ExecutionMode.SAME_THREAD
        defaultExecutionMode ExecutionMode.CONCURRENT
    }
}
  • Run tests ./gradlew --rerun-tasks :part1.0-introduction:test :part1.0-introduction:createTestsExecutionReport
  • Check reports

Isolated execution

diagram

  • Enable parallel execution (concurrent features, concurrent specifications)
  • Create a copy of class A and name it C
  • Run tests ./gradlew --rerun-tasks :part1.0-introduction:test :part1.0-introduction:createTestsExecutionReport
  • Check reports
  • Add @Isolated (spock.lang.Isolated) annotation to C class
  • Run test again ./gradlew --rerun-tasks :part1.0-introduction:test :part1.0-introduction:createTestsExecutionReport and check reports

Parallel thread pool

Supported options:

  • dynamic(BigDecimal factor)
  • dynamicWithReservedProcessors(BigDecimal factor, int reservedProcessors)
  • fixed(int parallelism)
  • custom(int parallelism, int minimumRunnable, int maxPoolSize, int corePoolSize, int keepAliveSeconds) (docs)

Default: dynamicWithReservedProcessors(1.0, 2) (Runtime.getRuntime().availableProcessors() * 1.0 - 2)

Example thread pool configuration:

runner {
    parallel {
        enabled true
        fixed(4)
    }
}

Check number of available processors:

jshell print-available-processors.jsh

Sample output:

Runtime.getRuntime().availableProcessors() = 10
  • Add test case to class A
def "test 3"() {
    sleep SLEEP_DURATION

    expect:
    true

    where:
    data << (1..20)
}
  • Remove class C
  • Run tests ./gradlew --rerun-tasks :part1.0-introduction:test :part1.0-introduction:createTestsExecutionReport -PtotalTimeOfAllTests=false
  • Check reports
  • Configure a thread pool of your choice, run tests and check reports
  • Randomize duration of tests. In test test 3 replace SLEEP_DURATION with new Random().nextLong(50, 250). Run tests and check reports.

home