Containers for Real Integration Tests

A presentation at NDC Porto in March 2019 in Porto, Portugal by Philipp Krenn

Slide 1

Slide 1

Containers for Real Integration Tests Philipp Krenn @xeraa

Slide 2

Slide 2

Developer

Slide 3

Slide 3

Tests

Slide 4

Slide 4

Slide 5

Slide 5

Slide 6

Slide 6

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

Slide 7

Slide 7

Slide 8

Slide 8

Slide 9

Slide 9

Slide 10

Slide 10

Slide 11

Slide 11

Slide 12

Slide 12

Integration Tests

Slide 13

Slide 13

Mocks

Slide 14

Slide 14

Mockito, EasyMock, JMock,…

Slide 15

Slide 15

Slide 16

Slide 16

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

Slide 17

Slide 17

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

Slide 18

Slide 18

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

Slide 19

Slide 19

In-Memory

Slide 20

Slide 20

H2, HSQLDB, Apache Derby,…

Slide 21

Slide 21

Slide 22

Slide 22

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

Slide 23

Slide 23

! Often good enough ! Test real datastore, supported systems

Slide 24

Slide 24

Actual Datastore

Slide 25

Slide 25

Local installation Docker container Cloud

Slide 26

Slide 26

Demo

Slide 27

Slide 27

! “Good old approach” ! External dependency, parallelization

Slide 28

Slide 28

Embedded

Slide 29

Slide 29

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

Slide 30

Slide 30

Demo

Slide 31

Slide 31

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

Slide 32

Slide 32

! IDE support, customization, custom lifecycle ! Custom integration

Slide 33

Slide 33

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

Slide 34

Slide 34

Build Tool

Slide 35

Slide 35

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

Slide 36

Slide 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>

Slide 37

Slide 37

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

Slide 38

Slide 38

Demo

Slide 39

Slide 39

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

Slide 40

Slide 40

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

Slide 41

Slide 41

Slide 42

Slide 42

Testcontainers Generic

Slide 43

Slide 43

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

Slide 44

Slide 44

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

Slide 45

Slide 45

Demo

Slide 46

Slide 46

What’s in docker ps -a

Slide 47

Slide 47

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

Slide 48

Slide 48

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

Slide 49

Slide 49

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

Slide 50

Slide 50

! IDE support, customization, custom lifecycle ! Hacky configuration

Slide 51

Slide 51

Testcontainers Custom

Slide 52

Slide 52

Slide 53

Slide 53

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

Slide 54

Slide 54

Demo

Slide 55

Slide 55

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

Slide 56

Slide 56

Selenium 2 / Webdriver VNC screen recording

Slide 57

Slide 57

! IDE support, customization, custom lifecycle ! Custom integration

Slide 58

Slide 58

Slide 59

Slide 59

Docker in Docker Or sidecar

Slide 60

Slide 60

$ 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

Slide 61

Slide 61

Conclusion

Slide 62

Slide 62

Why Integration Tests

Slide 63

Slide 63

Why not Mocking In-Memory Actual Datastore

Slide 64

Slide 64

How Embedded Build Tool Testcontainers

Slide 65

Slide 65

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

Slide 66

Slide 66

Questions? Philipp Krenn @xeraa