Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Integration and end-to-end testing with TestContainers-Go - Nikolay Kuznetsov & Erdem Toraman - Zalando

GoDays
January 23, 2020

Integration and end-to-end testing with TestContainers-Go - Nikolay Kuznetsov & Erdem Toraman - Zalando

TestContainers-Go is a port of a popular Java library TestContainers.

Go version still helps a developer to spin up throwaway real databases in Docker containers, i.e. Postgres, Redis, etc. Realistic integration tests could be run against those containers.

A list of features simplify developer life even more:
- Docker environment autodiscovery
- mapping to random unique host ports
- easy Docker network configuration and sharing
- waiting strategies for a ready status
- containers cleanup guarantees

In demo part integration tests against Postgres and Redis would be shown. For e2e test two services with their dependencies would be started.

GoDays

January 23, 2020
Tweet

More Decks by GoDays

Other Decks in Technology

Transcript

  1. About us • Go developers at Zalando in Helsinki •

    Project with ~20 microservices in Go • User perspective of TestContainers-Go library
  2. • Host port conflicts • Not ready сontainer / service

    • Resource leak (the container keeps running) • Stale data (if reusing the same container) • Starting mechanism both for CI and a local machine What could go wrong?
  3. TestContainers-Go github.com/testcontainers/testcontainers-go • Docker Go client under the hood •

    Host port randomization • Containers clean up at the test shutdown • Readiness waiting strategies
  4. Host port randomization • API to get a host port:

    • Prevents port conflicts • Enables parallel builds port, err := pgContainer.MappedPort(ctx, "5432/tcp")
  5. Containers cleanup: Ryuk github.com/testcontainers/moby-ryuk • Ryuk kills containers (networks, volumes)

    by labels • TC assigns labels to started containers • TC keeps a connection to Ryuk open
  6. Host port waiting strategy • Default (customizable) timeout is 60

    seconds • Impl checks both from outside and inside container tc.ContainerRequest{ Image: "postgres:12.1", ExposedPorts: []string{"5432/tcp"}, WaitingFor: wait.ForListeningPort("5432/tcp"), },
  7. What happened? • Ran a Postgres container • Mapped a

    random port to the host machine • Ran tests against it • Cleaned up the containers
  8. Takeaways • testcontainers.org • Balance between flexibility, speed and features

    • Great for integration tests • Possible to use for end-to-end tests