Integration testing with TestСontainers and JUnit 5
如果无法正常显示,请先停止浏览器的去广告插件。
相关话题:
#zalando
1. Integration testing with
TestСontainers and JUnit 5
Nikolay Kuznetsov
Zalando
@nikolayk812
Helsinki JUG
9 December 2019
2. About me
● Go developer at Zalando Wardrobe
● 6+ years of Java experience
● Conference speaker:
○ Voxxed Days Cluj, Container Days Hamburg
● TestContainers-Go contributor
3. Why integration testing?
4. 2 unit tests, 0 integration tests
5. Basic integration test
6. Trade-offs
7. Integration testing evolution
● In-memory mocking
● Local DBs
● Vagrant
● Docker / Docker Compose
● Docker API
8. Docker advantages
● 100% compatible database
● Same version as production
● Empty or known state
9. Docker architecture
10. How to start a container for test?
● Shell scripts
● Maven plugin
● Docker Compose
● Docker API
● MiniKube, Kubernetes
11. Shell scripts
12. Maven plugins
github.com/fabric8io/docker-maven-plugin
13. Docker Compose
14. Docker API
docs.docker.com/engine/api/latest
15. Exec example
16.
17. TestContainers flavors
18. TestContainers Java
● github.com/testcontainers/testcontainers-java
● Wraps docker-java library
● Docker environment discovery
● Host port randomization
● Containers clean up on JVM shutdown
● Readiness waiting strategies
19. As simple as
var redis = new GenericContainer("redis:5.0.6")
.withExposedPorts(6379);
var postgres = new PostgreSQLContainer();
20. Docker environment discovery
21. Talking to Docker via UDS
● curl --unix-socket /var/run/docker.sock
http:/localhost/containers/json
● curl --unix-socket /var/run/docker.sock
http:/localhost/networks
22. Host port randomization
● To prevent port conflicts
● Enables parallel builds
● API to get a host port
23. Containers cleanup
https://github.com/testcontainers/moby-ryuk
24. Waiting strategies
● Host port
● HTTP
● Log message
● Docker healthcheck
● Combined / Custom
25. Host port waiting strategy
● Default: at first exposed port with timeout of 60s
● Both from outside and inside container
26. Internal port check
27. HTTP waiting strategy
● Status & response body predicate
28. Demo setup
User Service
29. Demo scenario
User Service
INSERT INTO
SELECT FROM
30. Demo
github.com/nikolayk812/hjug-tc-demo
31. Demo recap
● JUnit 5 Extension API
● TestContainer modules
32. JUnit 5 extension points
● Life-cycle callbacks
● Conditional execution
● Parameter resolution
● Exception handling
33. JUnit 5 extension logic
● Implement interface(s) from o.j.j.api.extension package
○ i.e. BeforeEachCallback, ExecutionCondition
● Register with @ExtendsWith annotation
● See @Testcontainers for reference
34. TestContainers modules
● Preconfigured, optimized for testing
● Wrappers on top of GenericContainer class
● 14 databases
● MockServer, LocalStack, Kafka, ToxiProxy
35. Demo-2: setup
User Service
36. Demo-2: Docker network
User Service
localhost: 32812
user-alias: 8083
postgres-alias: 5432
37. Demo-2: scenario
User Service
POST /users
GET /user/<id>
38. Demo-2
github.com/nikolayk812/hjug-tc-demo
39. Demo-2: recap
● Docker network and alias
40. Why end-to-end testing?
● Business flows across multiple services
● Regression, when
○ + new service
○ - legacy service
41. Some cluster
Kubernetes
Spring Cloud
42. E2E strategies
● Against a deployed cluster
● Against on-demand in memory cluster
43. Deployed cluster cons
● Replace a service with a newer version => instability
● Temporary service name => non-discoverable
● Unexpected databases states
○ Care to clear data after the test?
44. On-demand cluster cons
● Time to start all containers
● Memory + CPU
● How actually to create it?
45. On-demand Kubernetes for E2E?
46. YAGNI
47. On-demand cluster TC approach
● Each service started by TestContainers
● Shared Docker network
● Functional tests
● Unless testing Kubernetes manifests
48. E2E setup
User Service
Item Service
49. Hints
● Host port forwarding
Testcontainers.exposeHostPorts()
● Fixed host port (for remote debugging)
GenericContainer.addFixedExposedPort()
● Reusable containers
github.com/testcontainers/testcontainers-java/issues/781
50. 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
51. Thank you!
@nikolayk812
nikolayk812
nikolayk812