A Java library that enables parallel execution of Spring Boot integration tests with embedded Camunda runtime. This library solves the challenge of running Camunda integration tests concurrently by providing the necessary infrastructure and utilities for test isolation.
Spring Boot integration tests with embedded Camunda runtime typically cannot run in parallel due to shared resources, database connections, and process engine state. This significantly increases CI/CD pipeline duration and slows down development feedback loops.
- Parallel Test Execution: Run multiple Camunda integration tests concurrently
- Resource Isolation: Automatic isolation of database connections and process engine instances
- Spring Boot Integration: Seamless integration with Spring Boot test infrastructure
- Easy Configuration: Minimal configuration required to enable parallel testing
- Camunda 7 Support: Built for Camunda BPM Platform 7 embedded in Spring Boot
Note: This library is currently in early development. Features are being actively implemented.
- Java 21+: Takes advantage of modern Java features and virtual threads
- Spring Boot 3.x: Compatible with Spring Boot 3.x series
- Camunda 7.x: Designed for Camunda BPM Platform 7 embedded in Spring Boot
- Gradle 8+ or Maven 3.6+: For building projects using this library
// build.gradle.kts
dependencies {
testImplementation("io.codepush.testing:camunda-test-parallel:0.1.0-SNAPSHOT")
}@ParallelFunctionalTest
class OrderProcessTest {
@Autowired
private RuntimeService runtimeService;
@Value("${wiremock.port.0}")
private int paymentServicePort;
@Test
void shouldProcessOrder() {
// Runs in isolated schema (camunda_test_<uuid>)
// WireMock port dynamically allocated — no conflicts
ProcessInstance instance = runtimeService
.startProcessInstanceByKey("orderProcess");
assertThat(instance).isNotNull();
}
}That's it. Each test class automatically gets:
- A unique PostgreSQL schema (
camunda_test_<uuid>) created before tests and dropped after - 3 dynamically allocated ports available as
${wiremock.port.0},${wiremock.port.1},${wiremock.port.2} - Spring Boot test context with
RANDOM_PORTweb environment andtestprofile
Add src/test/resources/junit-platform.properties:
junit.jupiter.execution.parallel.enabled=true
junit.jupiter.execution.parallel.mode.default=concurrent
junit.jupiter.execution.parallel.mode.classes.default=concurrent# src/test/resources/application-test.yml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/camunda_test
username: test_user
password: test_passwordThe library creates and drops isolated schemas automatically — your PostgreSQL user just needs CREATE permission on the database.
Pass additional Spring properties just like @SpringBootTest:
@ParallelFunctionalTest(
properties = {
"custom.feature.enabled=true",
"custom.timeout=5000"
}
)
class CustomFeatureTest { }Control how many ports are allocated per test class (default is 3):
// Allocate 5 ports: ${wiremock.port.0} through ${wiremock.port.4}
@ParallelFunctionalTest(wiremockPorts = 5)
class ManyExternalServicesTest { }
// Disable port allocation entirely
@ParallelFunctionalTest(wiremockPorts = 0)
class NoDependenciesTest { }@ParallelFunctionalTest
class PaymentServiceTest {
@Value("${wiremock.port.0}")
private int paymentPort;
private WireMockServer paymentMock;
@BeforeEach
void setUp() {
paymentMock = new WireMockServer(paymentPort);
paymentMock.start();
}
@AfterEach
void tearDown() {
paymentMock.stop();
}
@Test
void shouldCallPaymentService() {
paymentMock.stubFor(post("/charge")
.willReturn(ok()));
// test logic...
}
}Or in your application config:
# application-test.yml
payment-service:
base-url: http://localhost:${wiremock.port.0}
notification-service:
base-url: http://localhost:${wiremock.port.1}@Value("${spring.datasource.schema}")
private String schemaName; // e.g. "camunda_test_a1b2c3d4-..."-
Before each test class, the
ParallelTestExecutionListener:- Creates a unique PostgreSQL schema (
camunda_test_<uuid>) - Allocates dynamic ports by binding to port 0
- Injects schema name and ports into the test's Spring
ApplicationContextviaTestPropertyValues(context-isolated, not global)
- Creates a unique PostgreSQL schema (
-
After each test class, the listener:
- Drops the schema (
DROP SCHEMA ... CASCADE) - Releases the allocated ports
- Drops the schema (
All state is per-ApplicationContext — no System.setProperty pollution, no cross-test interference.
// Before
@SpringBootTest
class MyTest { }
// After
@ParallelFunctionalTest
class MyTest { }Existing properties and configuration are preserved. The annotation composes @SpringBootTest(webEnvironment = RANDOM_PORT), @EnableAutoConfiguration, and @ActiveProfiles("test").
- Install Docker and VS Code with the Dev Containers extension
- Clone and open:
git clone https://github.com/codepush-io/camunda-test-parallel.git cd camunda-test-parallel code .
- Click "Reopen in Container" when prompted
- Install Java 21
- Clone and build:
git clone https://github.com/codepush-io/camunda-test-parallel.git cd camunda-test-parallel ./gradlew build
./gradlew test # Unit tests
./gradlew integrationTest # Integration tests
./gradlew check # All testsWe welcome contributions! Please see our Contributing Guidelines for details on:
- Setting up your development environment
- Code style and standards
- Submitting pull requests
- Reporting issues
- Core parallel execution infrastructure
- Database schema isolation (PostgreSQL)
- Spring Boot test annotations (
@ParallelFunctionalTest) - Dynamic WireMock port allocation
- Context-isolated property injection
- Schema-aware DataSource wrapper
- Configurable WireMock port count
- Process engine instance isolation
- Testcontainers auto-provisioning
- Support for databases beyond PostgreSQL
- Example projects
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- Issues: Report bugs or request features via GitHub Issues
- Discussions: Join the conversation in GitHub Discussions
- Contributing: See CONTRIBUTING.md for how to get involved
This project is inspired by the need for faster feedback loops in Camunda-based applications and builds upon the excellent work of the Spring Boot and Camunda communities.