Testcontainers

A Year in Review

  • Software Engineer @ codecentric AG
    • ​Starting my PhD next month @ Institute for Internet Security
  • Consultant @ Styrascosoft GbR
  • Testcontainers Maintainer and Open Source Enthusiast
  • Oracle Groundbreaker Amabassador
  • Organizer Software Craftsmanship Meetup Ruhr

Kevin Wittek          @kiview

Thanks to Sergei!

(for slides and everything else)

@bsideup

Why do we Test?

Because else we might end up here!

My definiton

For example:

  • Launch application server
  • Framework/Library interactions
  • Interact with external ports (e.g. network, file system, database) 

"Tests which interact with external systems/dependencies"

But why a pyramid?

Testing Honeycomb

Integrated Tests

"I use the term integrated test to mean any test whose result (pass or fail) depends on the correctness of the implementation of more than one piece of non-trivial behavior." -  J.B. Rainsberger

"A test that will pass or fail based on the correctness of another system." - Spotify

Integrated Tests

For example:

  • We (manually) spin up other services in a local testing environment
  • We test against other services in a shared testing environment
  • Changes to your system breaks tests for other systems

Integration Testing Transformation

GenericContainer redis =
    new GenericContainer("redis:3.0.2")
               .withExposedPorts(6379);

redis.start();

// test my stuff

redis.stop();

The project

  • testcontainers-java first released in 2015
  • 100% OSS, MIT licensed
  • 65 releases, 149 contributors
  • Core maintainers
    • Richard North
    • Sergei Egorov
    • Kevin Wittek
  • Forks in Python, C#, Rust, Go, JS; Scala wrapper

Capabilities

  • Generic docker container support
    • use any Docker image to support tests
  • Databases (many!) and Stream processing (Kafka, Pulsar)
  • AWS mocks (Localstack)
  • Docker Compose
  • Selenium
  • Chaos testing

Capabilities (2)

  • Dynamic port binding and API
  • WaitStrategies
  • Docker environment discovery (e.g. docker-machine, DOCKER_HOST, Docker for Mac, Docker for Windows)
  • Platform independent
    • Linux, macOS, Windows 10 (with NPIPE support!)

@ashleymcnamara

Works on Windows too!

JDK12 Compatible!
+ regularly build against openjdk-ea

Users

Spock Extension


@Testcontainers
class TestContainersClassIT extends Specification {


    @Shared
    GenericContainer genericContainer = 
       new GenericContainer("postgres:latest")
            .withExposedPorts(5432)
            .withEnv([
                POSTGRES_USER: "foo"
                POSTGRES_PASSWORD: "secret"
            ])
}
// Set up a redis container
@ClassRule
public static GenericContainer redis =
    new GenericContainer("redis:3.0.2")
               .withExposedPorts(6379);

JUnit4 Rules

Testcontainers-Jupiter (JUnit5)

@Testcontainers
class SomeTest {

    @Container
    private MySQLContainer mySQLContainer = new MySQLContainer();

    @Test
    void someTestMethod() {
        String url = mySQLContainer.getJdbcUrl();
         // create a connection and run test as normal
    }
}

What happened so far...

Resources

Testcontainers - A Year in Review

By Kevin Wittek

Testcontainers - A Year in Review

  • 1,184