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

Devoxx MA: Testcontainers deep dive

Devoxx MA: Testcontainers deep dive

Sergei Egorov

November 12, 2019
Tweet

More Decks by Sergei Egorov

Other Decks in Programming

Transcript

  1. About me • Testcontainers co-maintainer • Staff Engineer at Pivotal’s

    Spring R&D, working on Project Reactor ⚛ • Berlin Spring User Group co-organizer • Developer tools geek @bsideup
  2. Some signs of having Integrated Tests are: • We spin

    up other services in a local testing environment • We test against other services in a shared testing environment • Changes to your system breaks tests for other systems https://labs.spotify.com/2018/01/11/testing-of-microservices/ @bsideup
  3. Unit testing • Simulation tests are green, yay! • Everything

    is mocked • DB is written by others, why should I test it? @bsideup
  4. Integration testing https://commons.wikimedia.org/wiki/File:Cd4007.jpg • Jeez, how did it passed the

    Unit testing? • Is it a smoke? @#$%! YES IT IS! • Who knew that 100w soldering gun was a bit too powerful for it? @bsideup
  5. System testing https://commons.wikimedia.org/wiki/File:UART_8250_Microchip.jpg • Takes a lot of time to

    solder • “Oh no, the power bus is too far away from my microchip!” • Interference between the components @bsideup
  6. Integration testing Real-world, but isolated testing Spot the issues before

    the real environment Can be run during the development You have to start real databases Should be cross-platform Slower than Unit testing Pros Cons @bsideup
  7. Mocking Local DBs VMs
 (Vagrant) Docker Fig
 (aka Docker Compose)

    Integration testing transformation @bsideup
  8. Docker Compose FTW! redis: image: redis ports: - "6379:6379" postgres:

    image: postgres ports: - "5432:5432" elasticsearch: image: elasticsearch:5.0.0 ports: - "9200:9200" @bsideup
  9. Declarative YAML redis: image: redis ports: - "6379:6379" postgres: image:

    postgres ports: - "5432:5432" elasticsearch: image: elasticsearch:5.0.0 ports: - "9200:9200" @bsideup
  10. No ports randomization redis: image: redis ports: - "6379:6379" postgres:

    image: postgres ports: - "5432:5432" elasticsearch: image: elasticsearch:5.0.0 ports: - "9200:9200" @bsideup
  11. Container per test? redis: image: redis ports: - "6379:6379" postgres:

    image: postgres ports: - "5432:5432" elasticsearch: image: elasticsearch:5.0.0 ports: - "9200:9200" @bsideup
  12. Mocking Local DBs VMs
 (Vagrant) Docker Fig
 (aka Docker Compose)

    Integration testing transformation @bsideup
  13. Mocking Local DBs VMs
 (Vagrant) Docker Fig
 (aka Docker Compose)

    Docker API Integration testing transformation @bsideup
  14. Testcontainers • Created by Richard North in 2015 • github.com/testcontainers/testcontainers-java

    • Wraps docker-java library • Docker environment discovery (Win, Mac, Linux) • Containers cleanup on JVM shutdown @bsideup
  15. As simple as PostgreSQLContainer postgresql = new PostgreSQLContainer() GenericContainer redis

    = new GenericContainer("redis:3") .withExposedPorts(6379) @bsideup
  16. Use case: testing of microservices • REST service • Java,

    Spring Boot • Redis, Kafka and PostgreSQL • Calls some other micro-services @bsideup
  17. @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = RANDOM_PORT) @ContextConfiguration(initializers = Initializer.class) public abstract class

    AbstractIntegrationTest { @ClassRule public static GenericContainer redis = new GenericContainer("redis:3.0.6") .withExposedPorts(6379); @ClassRule public static MockServerContainer mockServer = new MockServerContainer(); } @bsideup
  18. @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = RANDOM_PORT) @ContextConfiguration(initializers = Initializer.class) public abstract class

    AbstractIntegrationTest { @ClassRule public static GenericContainer redis = new GenericContainer("redis:3.0.6") .withExposedPorts(6379); @ClassRule public static MockServerContainer mockServer = new MockServerContainer(); } Still using all the Spring goodies! @bsideup
  19. @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = RANDOM_PORT) @ContextConfiguration(initializers = Initializer.class) public abstract class

    AbstractIntegrationTest { @ClassRule public static GenericContainer redis = new GenericContainer("redis:3.0.6") .withExposedPorts(6379); @ClassRule public static MockServerContainer mockServer = new MockServerContainer(); } External dependencies @bsideup
  20. Takeaways • https://testcontainers.org • Works on Linux, Mac and Windows

    • …including CIs like Jenkins, Travis, CircleCI, GH Actions, Azure Pipelines, … • Provides a great balance between 
 flexibility, usability, speed and features
 @bsideup