Test Jenkins Container with TestContainers Framework

Automate the Testing of your Infrastructure

Posted by Torsten Kleiber on March 26, 2022
Tags: Docker Infrastructure-as-Code Integration-Test Jenkins JUnit Maven TestContainers Virtual-Development-Server

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.

  1. As I want to use JUnit 5 as Wrapper I start with TestContainers JUnit 5 Quickstart Documentation.

  2. So I create a fresh pom.xml and added the required dependencies.

        <dependency>
          <groupId>org.junit.jupiter</groupId>
          <artifactId>junit-jupiter</artifactId>
          <version>5.8.2</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>org.testcontainers</groupId>
          <artifactId>testcontainers</artifactId>
          <version>1.16.3</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>org.testcontainers</groupId>
          <artifactId>junit-jupiter</artifactId>
          <version>1.16.3</version>
          <scope>test</scope>
        </dependency>
  3. Then I create my test class.

    @Testcontainers
    @DisplayName("Jenkins")
    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
      @DisplayName("first request to fresh container should return \"Authentication required\"")
      void firstRequestShouldReturnsAuthenticationRequiredTest()
          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.
  4. 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.

    virtual development server test with testcontainers slf4j warning
  5. To solve this you have to add the following dependency to your pom.xml.

        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>1.7.36</version>
        </dependency>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-simple</artifactId>
          <version>1.7.36</version>
        </dependency>
  6. 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
  7. 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>2.22.2</version>
          </plugin>
  8. 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!