Testcontainers making tests more reliable

Tests are important to challenge the developer to write better code. It helps in making sure no obvious scenarios are missed and gives confidence that the code will work fine.

Tests covered by developers:

  • Unit tests cover logic testing by mocking external dependencies
  • Data access layer integration tests cover testing of SQL queries compatibility with the database
  • Application integration tests brings up the short lived application with external dependencies in test mode and covers happy path tests along with untested edge cases
  • UI automation tests cover happy path user flow on frontend and are added very sparingly.

Apart from this, there are other tests as well, which has its own benefits. Considering all these tests, the most obvious question which developers have is

How many each type of tests should be covered?

And the answer is follow the Test Pyramid.

output-onlinepngtools (1) (2).png

The base layer indicates unit tests, the middle layer indicates the integration tests. The peak indicates the UI automation tests. And the rest is manual testing indicated by cloud.

Creating a reliable environment for running integration tests is a standard problem in most of the projects. The one major concern while setting up integration test is managing the database.

Traditional ways of managing database:

  • Usage of in-memory database like H2 might make your tests green, but the code will fail with real database and vice versa. Features offered by real database, might not be available with in-memory database. For e.g., MySQL offers encryption, but H2 does not support encryption.
  • Setting up a dedicated database instance for test is costly. And maintaining fresh state every time is also a challenge.
  • Spin containerized database comes with overhead of managing the life cycle.

Testcontainers mitigate this challenge by providing lightweight, throwaway instances of common databases or anything else that can run in a docker container while running tests like Integration Test. It can be used in UI/Acceptance tests as it provides containerized web browsers with Selenium support. For each test run, a clean state container can be provided. This library is helpful for making such tests reliable because of these programmable, lightweight and disposable containers.

Flexibility offered by Testcontainers:

  • Testcontainers manage external dependency which is containerized or can be containerized while running integration tests. It creates a docker image on-the-fly by providing Dockerfile.
  • Ability to decide, whether to spin new instance per test suite, or spin a single instance and share it across all test suites.
  • Ability to provide init script file and/or init function to be executed as soon as the container is up.

It is not all what testcontainers offers. To explore more, refer the official site.

Configuration of testcontainers in Spring Boot Project:

  1. Add following dependency in build.gradle

    testImplementation 'org.testcontainers:mysql:1.14.3'
    

    You can use latest version of testcontainers

  2. Update the application context for tests by updating application.properties or application.yaml file in test package

    spring:
     datasource:
       driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver
       url: jdbc:tc:mysql:8.0.20:///testcontainerdemo
    

    Here we just need to use the testcontainers driver and update the datasource url by adding tc between the jdbc and mysql. We don't need to mention host, port and database name as testcontainers will generate it on fly.

This is the straight forward way with minimum efforts to configure testcontainers.

Click here for complete source code.

Hope so you found this short introduction of testcontainers helpful. Explore more by referring the official site.

Please hit the reaction button once you are done reading.

ezgif-3-82ccd58cedc7.gif

Happy testing with Testcontainers!