Richtige Integrationstests mit Containern Philipp Krenn @xeraa

Developer

Tests

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

Integration Tests

Mocks

Mockito, EasyMock, JMock,…

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

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

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

In-Memory

H2, HSQLDB, Apache Derby,…

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

! Often good enough ! Test real datastore, supported systems

Actual Datastore

Local installation Docker container Cloud

Demo

! “Good old approach” ! External dependency, parallelization

Embedded

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

Demo

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

! IDE support, customization, custom lifecycle ! Custom integration

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

Build Tool

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

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>

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

Demo

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

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

Testcontainers Generic

Dependency @ClassRule public static GenericContainer redis = new GenericContainer(“redis:5.0.5”) .withExposedPorts(6379);

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));

Demo

What’s in docker ps -a

Docker for Mac API: socat Linux: Multipurpose relay (SOcket CAT) https://github.com/alpine-docker/socat

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

[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)

! IDE support, customization, custom lifecycle ! Hacky configuration

Testcontainers Custom

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

Demo

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

Selenium 2 / Webdriver VNC screen recording

! IDE support, customization, custom lifecycle ! Custom integration

Inside Containers

Wormhole Pattern

$ 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

Conclusion

Why Integration Tests

Why not Mocking In-Memory Actual Datastore

How Embedded Build Tool Testcontainers

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

Questions? Philipp Krenn @xeraa