Integration testing with Testcontainers on CrateDB

Testcontainers is a framework that allows provisioning Docker containers as part of your automated integration test runs. This way, you can run end-to-end tests of your application, including CrateDB. This tutorial focuses on Testcontainer’s Java/JUnit integration and shows how to boot up a single-node CrateDB database.

There is a complete example application available on GitHub. In this article, we will highlight its main aspects.

Add dependency

For this tutorial, we will use Gradle. CrateDB has its own Testcontainers database module which we add to the dependencies section of our build.gradle file, alongside the main Testcontainers dependency:

testImplementation "org.testcontainers:testcontainers:1.18.3"
testImplementation "org.testcontainers:cratedb:1.18.3"

Define CrateDB container

First, we define a @Before hook that starts CrateDB’s Docker image with the particular version we want to test against:

import org.junit.Before;
import org.junit.Test;

import org.testcontainers.cratedb.CrateDBContainer;
import org.testcontainers.utility.DockerImageName;

import java.io.IOException;
import java.sql.SQLException;

import static org.assertj.core.api.Assertions.assertThat;

public class TestCase {
    private CrateDBContainer cratedb;

    @Before
    public void startContainer() {
        DockerImageName image = DockerImageName.parse("crate:5.4.0").asCompatibleSubstituteFor("crate");
        cratedb = new CrateDBContainer(image);
        cratedb.start();
    }
}

Now we are able to connect to CrateDB from our application and can proceed with actual tests.

Simple first test

The referenced Application class is the actual application we want to test, and querySummitsTable is a function that accesses CrateDB.

    @Test
    public void testReadFromApplication() throws SQLException, IOException {
        // Get JDBC URL to connect to CrateDB
        String connectionUrl = cratedb.getJdbcUrl();

        // Invoke example test
        Application app = new Application(connectionUrl);
        var results = app.querySummitsTable();

        assertThat(results.metaData().getColumnCount()).isEqualTo(9);
        assertThat(results.rows()).hasSize(3);
        assertThat(results.rows().stream().map(r -> r[6]).toList()).containsExactly(
                "Mont Blanc",
                "Monte Rosa",
                "Dom");
    }

The test passes and everything works :rocket:.

Check out our full example application on GitHub for more test cases.

3 Likes