Integration and end-to-end testing with TestСontainers

Integration and end-to-end testing with TestСontainers

Fd8ac25831e3e9cc7d70944c77a369ef?s=128

Nikolay Kuznetsov

October 31, 2019
Tweet

Transcript

  1. Integration and end-to-end testing with TestСontainers Nikolay Kuznetsov @nikolayk812 31

    October 2019
  2. About me • Go developer at Zalando Helsinki • Java

    developer at Infobip, DevExperts • C developer at Samsung, Motorola
  3. Why integration testing?

  4. Trade-offs Test Runtime

  5. Basic integration test

  6. Integration testing evolution • In-memory mocking • Local DBs •

    Vagrant • Docker, Docker Compose • Docker API
  7. Docker advantages • 100% compatible database • Same version as

    production • Empty or known state
  8. Start Docker containers for integration test • Shell scripts •

    Maven plugin • Docker Compose • Docker API • MiniKube, Kubernetes
  9. Shell scripts

  10. Maven plugins github.com/fabric8io/docker-maven-plugin

  11. Docker Compose

  12. Docker API docs.docker.com/engine/api/latest

  13. None
  14. TestContainers • github.com/testcontainers/testcontainers-java • Wraps docker-java library • Docker environment

    discovery • Host port randomization • Containers clean up on JVM shutdown • Readiness waiting strategies
  15. As simple as static GenericContainer redis = new GenericContainer("redis:5.0.6") .withExposedPorts(6379);

    static PostgreSQLContainer postgres = new PostgreSQLContainer();
  16. Docker environment discovery

  17. Host port randomization • To prevent port conflicts • Enables

    parallel builds • API to get a host port
  18. Containers cleanup https://github.com/testcontainers/moby-ryuk

  19. Waiting strategies • Host port • HTTP • Log message

    • Docker healthcheck • Custom
  20. Host port waiting strategy • Default: at first exposed port

    with timeout of 60s • Implementation checks both from outside and inside container
  21. HTTP waiting strategy • Status & response body predicate

  22. Demo I github.com/nikolayk812/vdc-tc-demo User Service

  23. Demo recap • JUnit 5 integration via Extension API @TestContainers

    / @Container annotations • Modules ◦ wrappers on top of GenericContainer ◦ setters translated to containers environment variables
  24. JUnit 5 extensions • Test execution lifecycle phases = extension

    points • Extension logic ◦ Implement interface(s) from o.j.j.api.extension.* ◦ Register with @ExtendsWith annotation
  25. Modules • 14 database modules • MockServer • LocalStack =

    mocked AWS by Atlassian • Kafka, Pulsar, RabbitMQ • Toxiproxy
  26. Demo II Extensions Modules

  27. Demo III github.com/nikolayk812/vdc-tc-demo User Service Item Service

  28. Why end-to-end testing? • Test business flows across multiple services

    • Regression when ◦ a new service introduced ◦ a legacy service removed
  29. Testing environment cluster Spring Cloud Kubernetes

  30. Test cluster for automated E2E tests • Unexpected versions of

    dependencies ◦ Teammates deploy from a development branch ◦ Pinging other teams to stabilize their test environment • Unexpected database states ◦ Care to clear data generated by a test run?
  31. On-demand cluster for E2E tests • Locally and at CI

    machines • Needs time to spin up a new cluster • Resources: memory and CPU • How actually to do it?
  32. Kubernetes for E2E tests

  33. Non-Kubernetes for E2E tests • YAGNI = You aren’t gonna

    need it (Kubernetes for end-to-end tests) • Unless, you really want to test specific Kubernetes features or manifests • So, start services in containers within the same Docker network! (with TestContainers)
  34. E2E setup Item Service User Service Spring Cloud Netflix Eureka

  35. Docker network aliases item-alias :8084 user-alias :8083 postgres-alias :5432 redis-alias

    :6379 eureka-alias :8761
  36. Spring Cloud Eureka service names item-eureka user-eureka eureka

  37. Demo IV github.com/nikolayk812/vdc-tc-demo

  38. None
  39. E2E approach • Implement JUnit 5 extension for each service/database

  40. E2E approach (2) • An extension implements BeforeAllCallback interface •

    Starts a corresponding container via TestContainers API • Configures it, provides a shared a network • Perform tests by calling endpoints via host ports
  41. Demo V github.com/nikolayk812/vdc-tc-demo

  42. Hints • Host port forwarding Testcontainers.exposeHostPorts() • Fixed host port

    for remote debug GenericContainer.addFixedExposedPort() •
  43. Takeaways • https://testcontainers.org • Balance between flexibility, speed and features

    • Works on Mac, Linux, Windows • Great for integration tests • Possible to use for end-to-end tests
  44. Mulțumesc! @nikolayk812 nikolayk812