
Learn how to use Testcontainers to create lightweight, throwaway instances of ScyllaDB for testing
Why wrestle with all the complexities of database configuration for each round of integration testing? In this blog post, we will explain how to use the Testcontainers library to provide lightweight, throwaway instances of ScyllaDB for testing. We’ll go through a hands-on example that includes creating the database instance and testing against it.
Testcontainers: A Valuable Tool for Integration Testing with ScyllaDB
You automatically unit test your code and (hopefully) integration test your system…but what about your database? To rest assured that the application works as expected, you need to extend beyond unit testing. You also need to automatically test how the units interact with one another and how they interact with external services and systems (message brokers, data stores, and so on). But running those integration tests requires the infrastructure to be configured correctly, with all the components set to the proper state. You also need to ensure that the tests are isolated and don’t produce any side effects or “test pollution.” How do you reduce the pain…and get it all running in your CI/CD process?
This is where Testcontainers comes into play. Testcontainers is an open source library for throwaway, lightweight instances of databases (including ScyllaDB), message brokers, web browsers, or just about anything that can run in a Docker container. You define your dependencies in code, which makes it well-suited for CI/CD processes.
When you run your tests, a ScyllaDB container will be created and then deleted. This allows you to test your application against a real instance of the database without having to worry about complex environment configurations. It also ensures that the database setup has no effect on the production environment.
Some of the advantages of using Testcontainers with ScyllaDB:
- It launches Dockerized databases on demand, so you get a fresh environment for every test run.
- It isolates tests with throwaway containers. There’s no test interference or state leakage since each test gets a pristine database state
- Tests are fast and realistic, since the container starts in seconds, ScyllaDB responds fast, and actual CQL responses are used.
Tutorial: Building a ScyllaDB Test Step-by-Step
The Testcontainers ScyllaDB integration works with Java, Go, Python (see example here), and Node.js. Here, we’ll walk through an example of how to use it with Java.The steps described below are applicable to any programming language and its corresponding testing framework. In our specific Java example, we will be using the JUnit 5 testing framework.
The integration between Testcontainers and ScyllaDB uses Docker. You can read more about using ScyllaDB with Docker, and learn the Best Practices for Running ScyllaDB on Docker.
Step 1: Configure Your Project Dependencies
Before we begin, make sure you have:
- Java 21 or newer installed
- Docker installed and running (required for Testcontainers)
- Gradle 8
Note: If you are more comfortable with Maven, you can still follow this tutorial, but the setup and test execution steps will be different.
To verify that Java 21 or newer is installed, run:
java --version
To verify that Docker is installed and running correctly, run:
docker run hello-world
To verify that Gradle 8 or newer is installed, run:
gradle --version
Once you have verified that all of the relevant project dependencies are installed and ready, you can move on to creating a new project.
mkdir testcontainers-scylladb-java
cd testcontainers-scylladb-java
gradle init
A series of prompts will appear. Here are the relevant choices you need to select:
- Select
application
- Select
java
- Enter Java version:
21
- Enter project name:
testcontainers-scylladb-java
- Select application structure:
Single application project
- Select build script DSL:
Groovy
- Select test framework:
JUnit Jupiter
- For “Generate build using new APIs and behavior” select
no
After that part is finished, to verify the successful initialization of the new project, run:
./gradlew --version
If everything goes well, you should see a build.gradle
file in the app
folder.
You will need to add the following dependencies in your app/build.gradle
file:
dependencies {
// Use JUnit Jupiter for testing.
testImplementation libs.junit.jupiter
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
// This dependency is used by the application.
implementation libs.guava
// Add the required dependencies for the test
testImplementation 'org.testcontainers:scylladb:1.20.5'
testImplementation 'com.scylladb:java-driver-core:4.18.1.0'
implementation 'ch.qos.logback:logback-classic:1.4.11'
}
Also, to get test report output in the terminal, you will need to add testLogging
to app/build.gradle
file as well:
tasks.named('test') { // Use JUnit Platform for unit tests.
useJUnitPlatform()
// Add this testLogging configuration to get
// the test results in terminal
testLogging {
events "passed", "skipped", "failed"
showStandardStreams = true
exceptionFormat = 'full'
showCauses = true
}
}
Once you’re finished editing the app/build.gradle file, you need to install the dependencies by running this command in the terminal:
./gradlew build
You should see the BUILD SUCCESSFUL
output in the terminal.
The final preparation step is to create a ScyllaDBExampleTest.java
file somewhere in the src/test/java
folder. JUnit will find all tests in the src/test/java
folder.
For example:
touch src/test/java/org/example/ScyllaDBExampleTest.java
Step 2: Launch ScyllaDB in a Container
Once the dependencies are installed and the ScyllaDBExampleTest.java
file created, you can copy and paste the code provided below to the ScyllaDBExampleTest.java
file.
This code will start a fresh ScyllaDB instance for every test in this file in the setUp
method.
To ensure the instance will get shut down after every test, we’ve created the tearDown
method, too.
Step 3: Connect via the Java Driver
You’ll connect to the ScyllaDB container by creating a new session.
To do so, you’ll need to update your setUp
method in the ScyllaDBExampleTest.java
file:
Step 4: Define Your Schema
Now that you have the code to run ScyllaDB and connect to it, you can use the connection to create the schema for the database.
Let’s define the schema by updating your setUp
method in the ScyllaDBExampleTest.java
file:
Step 5: Insert and Query Data
Once you have prepared the ScyllaDB instance, you can run operations on it.
To do so, let’s add a new method to our ScyllaDBExampleTes
t class in the ScyllaDBExampleTest.java
file:
Step 6: Run and Validate the Test
Your test is now complete and ready to be executed!
Use the following command to execute the test:
./gradlew clean test --no-daemon
If the execution is successful, you’ll notice the container starting in the logs, and the test will pass if the assertions are met.
Here’s an example of what a successful terminal output might look like:
12:05:26.708 [Test worker] DEBUG com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager -- ep-00000012: connection released [route: {}->unix://localhost:2375][total available: 1; route allocated: 1 of 2147483647; total allocated: 1 of 2147483647]
12:05:26.708 [Test worker] DEBUG org.testcontainers.utility.ResourceReaper -- Removed container and associated volume(s): scylladb/scylla:2025.1
ScyllaDBExampleTest > testScyllaDBOperations() PASSED
BUILD SUCCESSFUL in 35s 3 actionable tasks: 3 executed
Full code example
The repository for the full code example can be found here: https://github.com/scylladb/scylla-code-samples/tree/master/java-testcontainers
Level Up: Extending Your ScyllaDB Tests
That’s just the basics. Here are some additional uses you might want to explore on your own:
- Test schema migrations – Verify that your database evolution scripts work correctly
- Simulate multi-node clusters – Use multiple containers to test your application with multi-node and multi-dc scenarios
- Benchmark performance – Measure your application’s throughput under various workloads
- Test failure scenarios – Simulate how your application handles network partitions or node failures
Wrap-Up: Master ScyllaDB Testing with Confidence
You’ve built a fast, real ScyllaDB test in Java that provides realistic database behavior without the overhead of a permanent installation. This approach should give you confidence that your code will work correctly in production.
You can try it with an example app on ScyllaDB University, customize it to your project and specific needs, and share your experience with the community!
Resources: Dive Deeper
- ScyllaDB Documentation
- ScyllaDB with Docker
- Best Practices for Running ScyllaDB on Docker
- Testcontainers
- GitHub Repository with Examples
- ScyllaDB University – Free courses to master ScyllaDB