Testcontainers is a set of open-source Java libraries that allow you to perform automatic integration tests by using a Docker container. The topic describes how to use Testcontainers to connect to and use OceanBase Database.
Prerequisites
- You have downloaded, installed, and started Docker.
- You have downloaded and installed IntelliJ IDEA.
- You have downloaded JDK 1.8.0.
- (Optional) You have downloaded Maven and configured it in IntelliJ IDEA.
Post-installation check
Check whether Docker has been installed:
docker -vYou do not need to manually start Docker. It will be automatically started or stopped when you run the sample application in subsequent steps.
Check whether JDK has been installed:
java -versionCheck whether Maven has been installed:
mvn -version(Optional) Check whether Maven has been correctly configured in IntelliJ IDEA:
This topic provides only a sample project for your reference. If you want to develop more complex projects, you can download Maven of a version suitable for your development environment and configure it in IntelliJ IDEA.
Check whether Maven has been installed:
mvn -versionOpen IntelliJ IDEA and choose IntelliJ IDEA > Settings > Build,Execution,Development > Build Tools > Maven. Set Maven home path to the installation path of Maven.

Procedure
- Decompress the downloaded sample project code and use IDEA to open the code.
- Run the sample project ExampleTest in src > test > java.
- If the following result is returned, the database is connected and the sample project is correctly executed.
...
53575 [main] INFO com.oceanbase.example.ExampleTest - Connect to OceanBase docker container successfully.
53577 [main] INFO com.oceanbase.example.ExampleTest - Prepare database and table.
53892 [main] INFO com.oceanbase.example.ExampleTest - Insert data to table `testcontainers`.`person`.
53928 [main] INFO com.oceanbase.example.ExampleTest - Query rows from `testcontainers`.`person`.
53932 [main] INFO com.oceanbase.example.ExampleTest - Row 0: name Adam, age 28.
53932 [main] INFO com.oceanbase.example.ExampleTest - Row 1: name Eve, age 26.
Project code introduction
Click Testcontainers to download the project code, which is a compressed package named TestcontainersDemo.zip.
After decompressing it, you will find a folder named TestcontainersDemo. The directory structure is as follows:
JDBCDemo
├── src
│ └── test
│ └── java
│ └── ExampleTest.java
└── pom.xml
File description:
src: the root directory for source code.test: the main code directory, containing the major logic of the application.java: the directory for storing the Java source code.ExampleTest.java: the main class, containing logic such as table creation and data insertion.pom.xml: the configuration file of the Maven project, used to manage project dependencies and build settings.
Introduction to pom.xml
The pom.xml file is the configuration file of the Maven project, which defines the dependencies, plugins, and build rules of the project. Maven is a Java project management tool that can automatically download dependencies, compile, and package the project.
The pom.xml file in this topic mainly contains the following parts:
Declaration statement.
Declare this file to be an XML file that uses XML standard
1.0and character encodingUTF-8.Sample code:
<?xml version="1.0" encoding="UTF-8"?>Configure namespaces and the POM model version.
- Use
xmlnsto specify the POM namespace ashttp://maven.apache.org/POM/4.0.0. - Use
xmlns:xsito specify the XML namespace ashttp://www.w3.org/2001/XMLSchema-instance. - Use
xsi:schemaLocationto specify the POM namespace ashttp://maven.apache.org/POM/4.0.0, and the URI of the corresponding XSD file ashttp://maven.apache.org/xsd/maven-4.0.0.xsd. - Use
<modelVersion>to specify the POM model version as4.0.0.
Sample code:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- Other configurations --> </project>- Use
Configure basic information.
- Use
<groupId>to specify the project group ascom.example. - Use
<artifactId>to specify the project name asJDBCDemo. - Use
<version>to specify the project version as1.0-SNAPSHOT.
Sample code:
<groupId>org.example</groupId> <artifactId>JDBCDemo</artifactId> <version>1.0-SNAPSHOT</version>- Use
Configure the external packages on which the project depends. Each dependency is defined with a groupId, artifactId, and version.
1. Use `<groupId>` to specify the dependency group. 2. Use `<artifactId>` to specify the dependency name. 3. Use `<version>` to specify the dependency version. 4. Use `<scope>` to specify the dependency scope. In this example, the dependency is only used in tests. **Sample code:** ```java <dependencies> <dependency> //If you use MySQL JDBC, you need to replace the values of groupId, artifactId, and version. <groupId>com.oceanbase</groupId> <artifactId>oceanbase-client</artifactId> <version>2.4.9</version> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>oceanbase</artifactId> <version>1.19.7</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.17.1</version> <scope>test</scope> </dependency> </dependencies> ```
Introduction to ExampleTest.java
The ExampleTest.java file is part of the sample project. It uses the Testcontainers framework and JUnit to create a test Java class.
It sets up a test environment that runs an OceanBase database container using Testcontainers and defines some basic configurations for the test class.
Sample code:
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; // Start of the test class definition public class ExampleTest { // Create an SLF4J Logger instance to log messages for the ExampleTest class private static final Logger LOG = LoggerFactory.getLogger(ExampleTest.class); // Create an OceanBase container instance using a specified Docker image and configure environment variables public static final OceanBaseCEContainer CONTAINER = new OceanBaseCEContainer("oceanbase/oceanbase-ce:4.2.2") .withEnv("MODE", "slim") // Set the environment variable MODE to slim .withEnv("FASTBOOT", "true") // Set the environment variable FASTBOOT to true .withLogConsumer(new Slf4jLogConsumer(LOG)); // Add a log consumer to record container logs using SLF4J // This method is executed before all tests to prepare the environment @BeforeClass public static void startContainers() { // Start the CONTAINER asynchronously and wait for it to complete Startables.deepStart(Stream.of(CONTAINER)).join(); // Log information about the started container, including the Docker image name, host address, and mapped ports LOG.info( "OceanBase docker container started, image: {}, host: {}, sql port: {}, rpc port:{}.", CONTAINER.getDockerImageName(), CONTAINER.getHost(), CONTAINER.getMappedPort(2881), CONTAINER.getMappedPort(2882)); } // This method is executed after all tests to clean up resources @AfterClass public static void closeContainers() { // Stop the container CONTAINER.close(); // Log a message indicating the container has stopped LOG.info("OceanBase docker container stopped."); } ```Write the test logic.
Sample code:
// Test the add and query operations in the database @Test public void test() { // Define the database and table names String database = "testcontainers"; String table = "person"; // Format the complete names of the database and table, using backticks to avoid conflicts with SQL keywords String tableName = String.format("`%s`.`%s`", database, table); // Output a log message indicating an attempt to connect to the OceanBase container LOG.info( "Try to connect to OceanBase docker container with url: {}.", CONTAINER.getJdbcUrl()); // Create a database connection to the OceanBase container try (Connection connection = CONTAINER.createConnection("?useSSL=false")) { LOG.info("Connect to OceanBase docker container successfully."); LOG.info("Prepare database and table.");Create a table.
Sample code:
// Create the database and table try (Statement statement = connection.createStatement()) { statement.execute("CREATE DATABASE IF NOT EXISTS " + database); statement.execute("USE " + database); statement.execute( "CREATE TABLE IF NOT EXISTS " + table + " (name VARCHAR(50), age INT)"); } catch (SQLException e) { throw new RuntimeException(e); }Insert data.
Sample code:
LOG.info("Insert data to table {}.", tableName); try (PreparedStatement ps = connection.prepareStatement("INSERT INTO " + tableName + " values(?, ?)")) { ps.setString(1, "Adam"); ps.setInt(2, 28); ps.executeUpdate(); ps.setString(1, "Eve"); ps.setInt(2, 26); ps.executeUpdate(); }Query data.
Sample code:
LOG.info("Query rows from {}.", tableName); try (PreparedStatement ps = connection.prepareStatement( "SELECT * from " + tableName, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) { ResultSet rs = ps.executeQuery(); int count = 0; while (rs.next()) { LOG.info("Row {}: name {}, age {}.", count++, rs.getString(1), rs.getInt(2)); }Handle exceptions.
Any exception that occurs during the preceding database operations will be captured, and error information along with stack trace details will be output.
Sample code:
} catch (SQLException e) { // Throw a runtime exception if an exception occurs throw new RuntimeException(e); }
Full code example
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.oceanbase.example</groupId>
<artifactId>testcontainers-java</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.oceanbase</groupId>
<artifactId>oceanbase-client</artifactId>
<version>2.4.9</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>oceanbase</artifactId>
<version>1.19.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.17.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
package com.oceanbase.example;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.lifecycle.Startables;
import org.testcontainers.oceanbase.OceanBaseCEContainer;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.stream.Stream;
public class ExampleTest {
private static final Logger LOG = LoggerFactory.getLogger(ExampleTest.class);
public static final OceanBaseCEContainer CONTAINER =
new OceanBaseCEContainer("oceanbase/oceanbase-ce:4.2.2")
.withEnv("MODE", "slim")
.withEnv("FASTBOOT", "true")
.withLogConsumer(new Slf4jLogConsumer(LOG));
@BeforeClass
public static void startContainers() {
Startables.deepStart(Stream.of(CONTAINER)).join();
LOG.info(
"OceanBase docker container started, image: {}, host: {}, sql port: {}, rpc port:{}.",
CONTAINER.getDockerImageName(),
CONTAINER.getHost(),
CONTAINER.getMappedPort(2881),
CONTAINER.getMappedPort(2882));
}
@AfterClass
public static void closeContainers() {
CONTAINER.close();
LOG.info("OceanBase docker container stopped.");
}
@Test
public void test() {
String database = "testcontainers";
String table = "person";
String tableName = String.format("`%s`.`%s`", database, table);
LOG.info(
"Try to connect to OceanBase docker container with url: {}.",
CONTAINER.getJdbcUrl());
try (Connection connection = CONTAINER.createConnection("?useSSL=false")) {
LOG.info("Connect to OceanBase docker container successfully.");
LOG.info("Prepare database and table.");
try (Statement statement = connection.createStatement()) {
statement.execute("CREATE DATABASE IF NOT EXISTS " + database);
statement.execute("USE " + database);
statement.execute(
"CREATE TABLE IF NOT EXISTS " + table + " (name VARCHAR(50), age INT)");
} catch (SQLException e) {
throw new RuntimeException(e);
}
LOG.info("Insert data to table {}.", tableName);
try (PreparedStatement ps =
connection.prepareStatement("INSERT INTO " + tableName + " values(?, ?)")) {
ps.setString(1, "Adam");
ps.setInt(2, 28);
ps.executeUpdate();
ps.setString(1, "Eve");
ps.setInt(2, 26);
ps.executeUpdate();
}
LOG.info("Query rows from {}.", tableName);
try (PreparedStatement ps =
connection.prepareStatement(
"SELECT * from " + tableName,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY)) {
ResultSet rs = ps.executeQuery();
int count = 0;
while (rs.next()) {
LOG.info("Row {}: name {}, age {}.", count++, rs.getString(1), rs.getInt(2));
}
assert count == 2;
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
References
- Testcontainers for Java documentation
- To use the Docker image of OceanBase Database, you need to use GenericContainer. For more information, see OceanBase Module.

Download the TestcontainersDemo sample project.