As I create my Virtual Development Servers I asked myself how can I easily test, that it is working? As I put now my servers into containers via docker-compose I searched for a test framework, which supports this out of the box. I heard a lot about TestContainers in the past and again at Javaland 2022 conference last week, so I want to test now, if this will help me.
In the last blog Run your Development Server on Docker Desktop on Windows I created a Docker Desktop Container, which is running on Windows. Now I want to test this Container with automated tests.
-
As I want to use JUnit 5 as Wrapper I start with TestContainers JUnit 5 Quickstart Documentation.
-
So I create a fresh pom.xml and added the required dependencies.
<dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.11.3</version> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>testcontainers</artifactId> <version>1.20.4</version> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>junit-jupiter</artifactId> <version>1.20.4</version> <scope>test</scope> </dependency>
-
Then I create my test class.
@Testcontainers @DisplayName("Jenkins") @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) class TestJenkins { public static final int JENKINS_PORT = 8080; @Container (1) public static DockerComposeContainer jenkinsServer = new DockerComposeContainer(new File("docker-compose.yml")) .withExposedService("jenkins", JENKINS_PORT) .waitingFor("jenkins", Wait.forLogMessage(".*Jenkins is fully up and running*\\n", 1)); (2) @Test void first_request_to_fresh_container_should_return_authentication_required() throws Exception { String jenkinsUrl = "http://" + jenkinsServer.getServiceHost("jenkins", JENKINS_PORT) + ":" + jenkinsServer.getServicePort("jenkins", JENKINS_PORT); MatcherAssert.assertThat("first request to fresh container should return \"Authentication required\"", callHttpEndpoint(jenkinsUrl), containsString("Authentication required")(3) ); } private static String callHttpEndpoint(String url) throws IOException, InterruptedException { (4) HttpClient httpClient = HttpClient.newBuilder().build(); HttpRequest mainRequest = HttpRequest.newBuilder() .uri(URI.create(url)) .build(); HttpResponse<String> response = httpClient.send(mainRequest, HttpResponse.BodyHandlers.ofString()); return response.body(); } }
1 I use the TestContainers Docker Compose Module here. 2 As most applications Jenkins is not fully started, when the conainer is started. So I wait until the suitable Jenkins message shows up in the Docker container logs. 3 In my test I call the Jenkins URL end the response should show for this container, that Authentication is required. 4 Here you see the helper method for calling an HTTP URL and return the response. -
If you run the test in your IDE, you will see a successful test, but following warning and miss maybe some logging for the call.
-
To solve this you have to add the following dependency to your pom.xml.
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.16</version> <scope>test</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>2.0.16</version> <scope>test</scope> </dependency>
-
If you run your test via Maven maybe you see now, that no test are executed.
------------------------------------------------------- T E S T S ------------------------------------------------------- Results : Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
-
For running Unit 5 tests you have to change the maven-surefire-plugin in your pom.xml at least to 2.22.0.
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.5.2</version> </plugin>
-
If you run your test now via Maven you should see an output similar like the following.
[INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running TestJenkins ... [main] INFO docker[docker/compose:1.29.2] - Creating container for image: docker/compose:1.29.2 [main] INFO docker[docker/compose:1.29.2] - Container docker/compose:1.29.2 is starting: 56fee4602485802e21ef5292d14e6fadeccefb676286fb691ac0af04f7e209f3 [main] INFO docker[docker/compose:1.29.2] - Container docker/compose:1.29.2 started in PT7.4233676S [main] INFO docker[docker/compose:1.29.2] - Docker Compose container is running for command: up -d ... [main] INFO docker[docker/compose:1.29.2] - Docker Compose has finished running [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 38.101 s - in TestJenkins [INFO] [INFO] Results: [INFO] [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] ... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
You can add a lot of other tests here, but for testing the TestContainers framework this should be enough here.
You find all sources on GitHub.
That’s it!