Self-hosted service
testcontainers/testcontainers-scala avatar
testcontainers/testcontainers-scala

testcontainers-scala wraps the Java library so Scala tests can start real services

Docker containers for testing in scala

667 stars136 forksScalaMIT

At a glance

What is it?
The testcontainers/testcontainers-scala project is an sbt based Scala wrapper around testcontainers-java, letting ScalaTest and MUnit suites start throwaway Docker containers such as databases or Selenium browsers during integration tests. It is a thin layer by design, and the module choice is left to you.
Who is it for?
Adopt testcontainers-scala when your Scala integration tests need a real database, a Selenium browser or another throwaway service, and your team is already on sbt with Docker available on the build machine. Do not adopt it for unit tests, which the README explicitly rules out by striking the word unit, or for projects that cannot run a Docker daemon during the build.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 30 days ago.
What is it written in?
Mainly Scala, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The wrapper is thin, and that is the point

The README describes the project in one sentence: a Scala wrapper for testcontainers-java that allows using Docker containers for functional, integration and, with a strikethrough, unit testing. That strikethrough on unit is the most informative word in the document. It tells you the author's position on scope, which is that this is for tests that need something real running, not for tests that need a mocked dependency. Underneath, the README describes Testcontainers as a Java 8 library that supports JUnit tests and provides lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container. So the value proposition is inheritance rather than invention. Scala teams already face the same problem as Java teams, where an integration test needs a database and the test either skips or needs a machine with that database installed. The Java library solved that. This project exists to make the same approach available from Scala code, with the Scala build tool and the Scala test frameworks as the only real additions.

Two test frameworks, and only two

The supported test frameworks are named explicitly in the README, and the list is short.

text
* [ScalaTest](https://www.scalatest.org/)
* [MUnit](https://scalameta.org/munit/)

That is the whole list, and the two entries point in different directions. ScalaTest is the older and much larger framework, with styles ranging from fun suites to behaviour driven specifications, and it is the framework most existing Scala codebases already run. MUnit is the newer, smaller option from the Scala centre, built around function suites and a small surface area. Supporting exactly these two means the wrapper has to provide a way to manage the container lifecycle in each of their idioms, and it means there is a well defined answer when you ask whether a given framework works. It also means a third framework is not supported, and if your project standardised on something else you are out of luck. That is worth checking before anything else, because it is a property of the wrapper rather than of the underlying Java library.

Choosing a module is the first decision the docs push onto you

The documentation list in the README starts with setup and modules choice, and the point of that page is that the project is a multi-module sbt build rather than a single artifact. The repository layout backs this up. At the top level there is build.sbt, a project/ directory holding the sbt build definition, a core/ directory, a modules/ directory, a test-framework/ directory, a docs/ directory, and a bin/ directory. The Maven Central badge in the README points at the artifact com.dimafeng/testcontainers-scala_2.12, which tells you the published coordinates and that the artifact is cross built against a specific Scala binary version, 2.12 in that badge. The practical consequence is that there is more than one way to depend on this library, and the choice affects which extra dependencies you pull in and which container types are available. The README treats that page as the starting point for setup, which is a sensible place to begin since a wrong module choice shows up as a missing class rather than a clear error message.

A Scala build means sbt, scalastyle and a JVM options file

The repository tells you what the build environment looks like without stating it as prose. There is a build.sbt, which is the standard sbt build file, a project/ directory for the build definition itself, a .jvmopts file that sets JVM options for the build, and a scalastyle-config.xml file holding the Scalastyle rules for the code. There is also a scalacheck_doc.md file, which points to ScalaCheck as a property based testing dependency in the documentation, and a CONTRIBUTING.md for the contribution rules. A bin/ directory at the top level is where a repository of that shape usually keeps helper scripts. Together these files describe a conventional JVM Scala project: sbt for building, Scalastyle for linting, and ScalaCheck available for property based tests. The absence of a Maven or Gradle build is the important part, since the build tool is fixed for you and the artifacts are published for it.

The upgrade guide is a separate page, which tells you the API moves

The documentation list in the README names four items: setup and modules choice, usage, an upgrade guide, and a blog post showing testcontainers-scala in action with Selenium from 2016. The presence of a dedicated upgrade guide is the signal here. A wrapper library exists to give a consistent API over an upstream library, and when the upstream library changes its own API, the wrapper has to change with it, and that change is visible to every user of the wrapper. The blog post link is dated 2016 and the framework list mentions MUnit, which did not exist then, so the project has moved on from its early example. The release notes live in the repository as release-notes.md and the README points at them for the details of each change. So the documentation surface is: an upgrade guide for people moving between versions, release notes for what changed, and a usage page for the current API. A team adopting this should read the upgrade guide before it upgrades anything else.

A Docker daemon on the build machine is an unstated hard requirement

Here is the constraint the README does not spell out. Testcontainers works by starting real containers, so a Docker daemon has to be reachable from the machine running the tests, and the images have to be pullable. That is a property of the whole approach rather than of this wrapper, but it lands on your CI. A build agent with no Docker socket, or a restricted environment that cannot reach a registry, cannot run these tests, and the failure will look like a test error rather than a configuration error. The README also describes the containers as throwaway, which is the correct mental model and has an important consequence for test design. Since the instance is created for the test and then discarded, a test that depends on state surviving between two test methods is testing something the library does not promise to provide. The blog post link about using the library with Selenium is the clearest illustration of the intended shape: start a browser container, drive it, throw it away.

Where a plain Docker client script fits instead

The realistic alternative is not another Scala library but a different testing strategy: a shell or Docker Compose script that starts the service before the suite and tears it down after, with the test code connecting to a fixed host and port. The difference in approach is where the lifecycle knowledge lives. Testcontainers puts the container inside the test process, so each test or suite owns its own instance, ports are assigned dynamically rather than fixed, and the container starts and stops with the code, which removes the ordering problem and the leftover container problem. The compose approach moves all of that out of the test run, which means it is simpler to debug when something fails, works in environments where the test process cannot reach the Docker socket but the shell can, and is reusable across several suites. The cost is that a fixed port has to be agreed on, that a stale container from a previous run can corrupt a result, and that starting a database takes the same wall clock time either way. For a single suite that talks to one database, the script is often less machinery. For a suite where different tests need different services, the per-test lifecycle is the reason to stay with the wrapper.

Editorial conclusion

Adopt testcontainers-scala when your Scala integration tests need a real database, a Selenium browser or another throwaway service, and your team is already on sbt with Docker available on the build machine. Do not adopt it for unit tests, which the README explicitly rules out by striking the word unit, or for projects that cannot run a Docker daemon during the build. Verify first by reading docs/src/main/tut/setup.md to pick the right module, since the build is a multi-module sbt project with core/, modules/ and test-framework/ directories, and check release-notes.md, because the most recent tagged release is v0.44.1 from 2025-12-23 while the last push was on 2026-09-23.

Frequently asked questions

Which test frameworks does testcontainers-scala support?

The README names ScalaTest and MUnit as the supported test frameworks, and that list is exhaustive. The project is a Scala wrapper for testcontainers-java, the Java 8 library that provides throwaway instances of databases, Selenium browsers or anything else that runs in a Docker container.

How do I add testcontainers-scala to an sbt project?

The README does not give a dependency block, and it points to the setup and modules choice page at docs/src/main/tut/setup.md for that. The Maven Central badge shows the published coordinates as com.dimafeng/testcontainers-scala_2.12, and the build is an sbt project with core/, modules/ and test-framework/ directories, so the module you pick depends on which container types you need.

Can I use testcontainers-scala for unit tests?

The README describes the project as allowing Docker containers for functional and integration testing, with the word unit struck through in the original. The intent is integration level testing where a real service is needed, not unit tests with mocked dependencies.

What is the latest release of testcontainers-scala?

The recent releases list ends with v0.44.1 dated 2025-12-23, preceded by v0.44.0 from 2025-11-24 and v0.43.6 from 2025-10-26. The last push to the repository was on 2026-09-23, and the detailed history is kept in release-notes.md.

What licence is testcontainers-scala released under?

The project is licensed under MIT, with the LICENSE file at the top level of the repository alongside the sbt build files, CONTRIBUTING.md and the release notes.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. testcontainers/testcontainers-scala on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/testcontainers-testcontainers-scala.svg)](https://hysenlabs.com/projects/testcontainers-testcontainers-scala)

Was this useful?