Integration Testing on JVM Integration tests for JVM web services should be placed in a separate module to keep fast unit tests fast and ensure honest dependency boundaries. The environment—including databases, message brokers, and HTTP stubs—must start before the server, with all dependencies binding to ephemeral ports to avoid conflicts and enable parallel execution. Unit tests tell me a function does what I think it does. They don’t tell me my service starts, binds its ports, reads its config, talks to a database, consumes from Kafka, and survives an LLM provider returning a 503 mid-stream. That second category is where most production incidents live, and it’s the one I care about most. This post lays out the integration-testing process I’ve converged on for JVM web services. The examples come from three repositories you can clone and run: koog-spring-boot-assistant Spring Boot + WebFlux , quarkus-assistant-demo Quarkus , and Mokksy for the Docker-image variant . They’re Kotlin because suspending functions and a fluent DSL make these tests pleasant to read — but everything here applies to Java too, and with virtual threads on Java 21+ you get the same ergonomics without coroutines. Assume a typical service: a REST API, perhaps a WebSocket or messaging endpoint Kafka/SQS , a database, and an outbound dependency or two — here, an LLM provider. The system under test SUT is a real, booted application, not a sliced @WebMvcTest context. Put end-to-end tests in their own module The decision that pays off most: integration tests live in a separate module , not in src/test alongside your unit tests. In the koog repository the root pom.xml declares two modules: 1