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

Real Integration Tests with TestContainers

Real Integration Tests with TestContainers

How are you doing integration tests with your datastore?

* Mocking is not an option since you want to test the actual system.
* There are some in-memory implementations, like H2 or HSQLDB for relational databases, but there are still subtle differences to your production system and not all datastores have in-memory cousins.
* Using the actual datastore in your tests is possible, but managing it, running tests in parallel,... is far from ideal.

So what is the solution? There is a very neat solution based on containers: TestContainers. From your tests you can start a lightweight, throwaway instance of your datastore and this talk will walk you through on how to do that as well as alternatives with docker-maven-plugin.

Philipp Krenn

January 29, 2019
Tweet

More Decks by Philipp Krenn

Other Decks in Programming

Transcript

  1. Containers
    for Real Integration Tests
    Philipp Krenn̴̴̴@xeraa

    View Slide

  2. Developer

    View Slide

  3. Tests

    View Slide

  4. View Slide

  5. View Slide

  6. But the unit tests
    passed, so...
    https://twitter.com/Aaronius/status/
    933497253347463168

    View Slide

  7. View Slide

  8. View Slide

  9. View Slide

  10. View Slide

  11. View Slide

  12. Integration
    Tests

    View Slide

  13. Mocks

    View Slide

  14. Mockito, EasyMock,
    JMock,...

    View Slide

  15. View Slide

  16. Ich mock mir die Welt
    widdewidde wie sie mir
    gefällt

    View Slide

  17. https://www.monkeyuser.com/2018/
    happy-flow/

    View Slide

  18. !
    Unit tests, systems not
    under your control
    !
    Test real datastore

    View Slide

  19. In-Memory

    View Slide

  20. H2, HSQLDB, Apache
    Derby,...

    View Slide

  21. View Slide

  22. Embedded Elasticsearch
    unsupported in 5.0+
    https://www.elastic.co/blog/elasticsearch-the-server

    View Slide

  23. !
    Often good enough
    !
    Test real datastore,
    supported systems

    View Slide

  24. Actual
    Datastore

    View Slide

  25. Local installation
    Docker container
    Cloud

    View Slide

  26. Demo

    View Slide

  27. !
    "Good old approach"
    !
    External dependency,
    parallelization

    View Slide

  28. Embedded

    View Slide

  29. embedded-elasticsearch
    https://github.com/allegro/embedded-elasticsearch

    View Slide

  30. Demo

    View Slide

  31. Customization & Mappings
    .withPlugin("analysis-stempel")
    .withIndex("cars", IndexSettings.builder()
    .withType("car", getSystemResourceAsStream("car-mapping.json"))

    View Slide

  32. !
    IDE support,
    customization, custom
    lifecycle
    !
    Custom integration

    View Slide

  33. More embedded
    datastores
    https://github.com/flapdoodle-oss/
    de.flapdoodle.embed.process

    View Slide

  34. Build Tool

    View Slide

  35. docker-maven-plugin
    http://dmp.fabric8.io

    View Slide

  36. Dockerfile or Docker assembly

    java:8

    docker-assembly.xml


    java -jar /maven/service.jar


    View Slide

  37. Build a custom image:
    docker:build
    Run container:
    docker:start
    docker:stop

    View Slide

  38. Demo

    View Slide

  39. maven-failsafe-plugin
    https://maven.apache.org/surefire/maven-failsafe-plugin/

    View Slide

  40. !
    Standard or custom
    Docker image
    !
    One instance for all
    tests, no IDE support

    View Slide

  41. Testcontainers

    View Slide

  42. Dependency
    @ClassRule
    public static GenericContainer redis =
    new GenericContainer("redis:3.0.2")
    .withExposedPorts(6379);

    View Slide

  43. Docker Compose integration
    @ClassRule
    public static DockerComposeContainer environment =
    new DockerComposeContainer(new File("src/test/resources/compose.yml"))
    .withExposedService("elasticsearch_1", ELASTICSEARCH_PORT,
    Wait.forHttp("/").forStatusCode(200));

    View Slide

  44. Demo

    View Slide

  45. !
    IDE support,
    customization, custom
    lifecycle
    !
    Hacky configuration

    View Slide

  46. Cleanup: Moby Ryuk
    https://github.com/testcontainers/moby-ryuk

    View Slide

  47. [Ryuk] drops a Death
    Note, a notebook that
    allows the user to kill
    anyone simply by
    knowing their name
    and face
    https://en.wikipedia.org/wiki/Ryuk_(Death_Note)

    View Slide

  48. View Slide

  49. ElasticsearchContainer
    https://www.testcontainers.org/modules/elasticsearch/

    View Slide

  50. Demo

    View Slide

  51. More languages
    Scala, Go, .net*, Python*, JavaScript*, Rust*
    * Early development

    View Slide

  52. Selenium 2 / Webdriver
    VNC screen recording

    View Slide

  53. !
    IDE support,
    customization, custom
    lifecycle
    !
    Custom integration

    View Slide

  54. View Slide

  55. Docker in Docker
    Or sidecar

    View Slide

  56. $ docker run -it
    --rm
    -v $PWD:$PWD
    -w $PWD
    -v /var/run/docker.sock:/var/run/docker.sock
    maven:3 mvn --projects parent,4_testcontainers-custom test
    $ docker ps -a

    View Slide

  57. Conclusion

    View Slide

  58. Why
    Integration Tests

    View Slide

  59. Why not
    Mocking
    In-Memory
    Actual Datastore

    View Slide

  60. How
    Embedded
    Build Tool
    Testcontainers

    View Slide

  61. Code
    https://github.com/xeraa/integration-test-demo

    View Slide

  62. Questions?
    Philipp Krenn̴̴̴̴@xeraa

    View Slide