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.

Ce4685da897c912aa41a815435b40a5a?s=128

Philipp Krenn

January 29, 2019
Tweet

Transcript

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

  2. Developer

  3. Tests

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

  7. None
  8. None
  9. None
  10. None
  11. None
  12. Integration Tests

  13. Mocks

  14. Mockito, EasyMock, JMock,...

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

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

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

    real datastore
  19. In-Memory

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

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

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

  24. Actual Datastore

  25. Local installation Docker container Cloud

  26. Demo

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

  28. Embedded

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

  30. Demo

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

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

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

  34. Build Tool

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

  36. Dockerfile or Docker assembly <build> <from>java:8</from> <assembly> <descriptor>docker-assembly.xml</descriptor> </assembly> <cmd>

    <shell>java -jar /maven/service.jar</shell> </cmd> </build>
  37. Build a custom image: docker:build Run container: docker:start docker:stop

  38. Demo

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

  40. ! Standard or custom Docker image ! One instance for

    all tests, no IDE support
  41. Testcontainers

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

  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));
  44. Demo

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

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

  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)
  48. None
  49. ElasticsearchContainer https://www.testcontainers.org/modules/elasticsearch/

  50. Demo

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

    development
  52. Selenium 2 / Webdriver VNC screen recording

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

  54. None
  55. Docker in Docker Or sidecar

  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
  57. Conclusion

  58. Why Integration Tests

  59. Why not Mocking In-Memory Actual Datastore

  60. How Embedded Build Tool Testcontainers

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

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