Hi everyone,
Currently we seem to have a bit of a gap for testing solutions in the MicroProfile/JavaEE space, especially when it comes to integration testing. The current best option is Arquillian, but I have personally struggled with this framework a lot and I do not find it easy to use as an application developer, and it also does not always have consistent dev/prod behavior parity.
I would like to propose a simple, user-facing integration test framework based on Docker. The main idea is that the integration test framework actually starts up a container of your app, and then you write client-side tests to perform black-box testing of the application's running container. I originally outlined this concept in
a blog post earlier this year.
The setup/prereqs for this test framework is simple:
1) Have Docker installed locally, or have access to a remote Docker host
2) Add a single test-scoped maven dependency
3) (optional) Have a Dockerfile in your repo, or have access to a pre-built image you would like to test
From there, we can leverage a popular existing Java library called
Testcontainers to build (if needed), start, and stop the container.
Suppose we want to test a simple HelloService JAX-RS endpoint. The integration test would look something like this:
@MicroProfileTest
public class HelloServiceTest {
@Container // This automatically starts the app container before the test runs
public static MicroProfileApplication app = new MicroProfileApplication()
.withContexRoot("/myservice");
@Inject // This gives us a REST client proxy (similar to MP Rest Client) for interacting with the remote service
public static HelloService helloSvc;
@Test
public void testHelloEndpoint() {
// Using the injected REST client proxy, we can easily invoke HTTP requests to the running container and read the response
assertEquals("Hello world!", helloSvc.sayHello());
}
}
I believe this has several key advantages over existing solutions:
- Test the app _exactly_ as it would run in production (aside from env vars or mounted secrets)
- Easy to set up and run
- Works for any MicroProfile implementation already -- little/no vendor-specific code needs to be implemented or maintained
- Integrates seamlessly with external resources (databases, external HTTP services, or messaging engines) because external resources were the original purpose for Testcontainers
- Server-side logs are merged with JUnit output, making it easy to correlate server logs with their corresponding client-side test
I have currently tested a JAX-RS + CDI + MongoDB + MP Rest Client app successfully with:
- OpenLiberty / WAS Liberty
- Wildfly
- Payara Micro
- TomEE
(Also works with Quarkus, but Quarkus already has its own custom testing framework)
Next steps:
Since this approach has more to do with Docker/Testcontainers than MicroProfile, I was thinking the best home for this project would be in the
Testcontainers org. I have approached the Testcontainers org and they seem interested and excited about this new framework, and are willing to accept it under their org. I would like to invite other MP folks to give it a try (instructions in the README) and offer feedback. Of course, any contributions or collaboration is encouraged!
Looking forward to hearing people's comments and questions on this.
- Andy