Testcontainers & Developer relations at Docker.
Oleg Šelajev is a developer advocate at Docker working mainly on developer productivity, Testcontainers, and improving how we set up local development environments and tests. Developer. Author. Speaker. Java Champion. Docker captain.
Loves all languages.
Area of Expertise
We always seek ways to enhance productivity and streamline workflows. Traditional YAML-based tools with origins in production systems are beneficial for managing stable environments but often introduce complexity to the inner loop.
In this session, we explore how common tasks, defining setups and environments for tests, local execution, necessary cloud counterparts, and CI/CD pipelines look when a developer has API for them in their favorite programming language and can use these straight from the application code.
We'll showcase real-world examples demonstrating how this programmatic approach integrates into existing ecosystems and adapts to various scales of development.
Ultimately, the session might inspire you to create more developer-friendly environments and enable more reliable and efficient application development.
Despite the quality of modern cloud-native tools, the user experience for the inner and outer loops are still radically different, which introduces friction and slows down developer productivity.
Development setups are application-centric, while production environments deal with deployments and tools required for operations teams to keep applications up and running. In this session, we explore tools to simplify both sides to improve developer productivity by following a platform engineering and polyglot approach.
This session demonstrates and provides hands-on experience on:
How to enable developers with standard application-level APIs to solve common distributed application challenges by using Dapr.
How to equip developers and product managers with consistent and polyglot feature flags with OpenFeature.
And how to develop locally with these tools, outside of a Kubernetes Cluster, by using Testcontainers.
Flow state, cognitive load, and speed of feedback loops are three core dimensions of developer experience. Taken together, they encapsulate almost all friction encountered in the development process.
However, these can be hard to measure and sometimes straightforward to improve.
In this session, we show how tests, the test suites' quality, and running test experience cover all three core dimensions and enable high-performing teams.
We look at anti-patterns for tests and how they drastically increase the cognitive load required even for the most straightforward changes and slow down feedback loops.
Then we show how modern high-quality test setups ensure developer productivity and happiness and drive team velocity up and to the right.
Below is the small print and not part of the abstract:
Some useful materials:
We'll show testcontainers based setups for test -- ensuring environment parity, ease of running individual tests, flexibility of configuration, debuggability of the tests; talk about performance improvements to test suites, how higher level integration tests aren't too tied to implementation details allowing easier changes, and how they give a lot of confidence without requiring too much maintenance.
Tests are essential to developer productivity, but without proper care, they quickly stop being a fun way to know if the code is working and become a chore!
The best way to avoid this pitiful situation is to use libraries that simplify everyday tasks making working with tests a joy!
In this session, we'll look at a collection of libraries making tests enjoyable. Libraries that take care of the chores from environment setup, to generating test data, to working with asynchronous events without the silliness of timeouts, to fluently working with network queries, to mocking whole services like a pro!
Join us for a quick and fun overview of what libraries you should add to your projects and how they all combine to make tests bring joy!
JUnit 5 advanced features, awaitility, restassured, testcontainers
Working with data: instancio, synthesized tdk, wisser/jailer
Pi-test for mutation tests
Testcontainers libraries are a de-facto standard for integration testing in the Java community. One of the reasons for its popularity is the ecosystem of the modules -- pre-defined abstractions for creating containerized services for your tests in a single line of code.
Testcontainers modules help to integrate with new technologies, hide setup complexity behind a neat abstraction, or use in-house Docker images without using lower-level API all the time.
In this lab, we'll go over the architecture of a module, see how one can implement it, and make a small but helpful module ourselves.
Whether you're working on a database technology, want to implement chaos engineering practices, or improve your team's productivity, creating a Testcontainers module is an excellent way to abstract away some of the complexity of your integration tests and contribute to the Java ecosystem.
Making a Testcontainers module can be a great exercise -- either adding a more complex topology (adding a chaos engineering proxy and hiding it behind an abstraction, supporting your in-house docker images, or a new technology -- all these are great use cases and you can contribute to the Java ecosystem in a nice standalone way (without taking on yourself a ton of responsibility for maintaining the project forever).
Many applications rely on cloud solutions like AWS, Azure, and GCP. Testing such applications could be a nightmare of spare cloud accounts or never-ending environment setups.
Thanks to Testcontainers, we can run all the necessary services locally and even more programmatically control their configuration and lifecycle! It means you can improve your development feedback loop locally and test your cloud-native applications without spending a penny.
In this demo-heavy session, we’ll go over typical use cases cloud-native app developers struggle to test effectively, and look at how Testcontainers features enable working with S3, DynamoDB, Lambdas, Google Spanner, and others. Testing your cloud-native applications with Localstack and GCloud modules has never been this easy and reliable.
Unit testing is fine, but without proper integration testing, especially if you work with external resources like databases and other services, you might not know how your application will actually behave once it has been deployed to the real production environment.
Before Testcontainers, configuring the environment for integration testing was painful – people were using fake database implementations, mocking servers, usually it was not cross-platform as well. However, thanks to containers, now we can quickly prepare the environment for our tests.
In this deep drive, we would like to show how you can use Testcontainers, a popular JVM testing library that harnesses containers to easily, reliably, spin up test dependencies. We will learn how to use it for testing legacy application in an out-of-process approach, but also how you can leverage it to boost your developer productivity when used in conjunction with modern microservice frameworks such as Spring-Boot, Quarkus, or Micronaut.
We will also have a look at some of the internals of Testcontainers, so that you will learn how to extend this modular library for the needs of your projects.
Are you a Java developer making the first steps with cloud based technologies? Is learning Kubernetes the hard way a bit too... hard?
Worry not! In this session, we'll go over the fundamentals of k8s to make your journey into using it simpler and more enjoyable.
In a true Java fashion we'll start with a Factory... kidding! with a test-driven exploration of what k8s is, its concepts and capabilities and learn why it's such a powerful tool.
We'll write tests that spin real k8s clusters with Testcontainers, explore what happens inside, break the assumptions, and truly get that first hands-on experience that'll make you both confident and a bit dangerous at working with this 10-letter staple of the clouds.
PS. there will be yaml, but as little as possible, pinky promise!
Applications today don't exist in a vacuum. They typically communicate with other services, such as databases, message brokers, cache servers, and more. These interconnectivity requirements make it hard to do local/inner-loop development and testing efficiently, often forcing developers to write lots of code and configuration that never gets to production.
What if there was a better way? What if you didn’t need to write any extra code or configuration and things just worked out of the box, making your life simpler and easier?
This session will introduce Testcontainers and explore the synergy between Testcontainers and Quarkus, showcasing all the integration that has been done for you, the developer, so that you don’t need to worry about anything!
We did this session with Eric Deansdrea (Red Hat), and it turned out pretty well: https://www.youtube.com/watch?v=x44dL5jzaG4
Applications don't exist in a vacuum. They must communicate with other services via message brokers, databases, or directly with each other. This dependency on other services, third-party or developed in-house, often presents challenges to efficient inner loop development and testing.
Contract tests provide an approach to describe and verify API and efficiently implement integration tests for the other party.
In this session, we explore how you could implement contract tests for your services, how contract and integration tests complement each other, and how to organize communication between the teams to improve your development processes.
Testcontainers & Developer relations at Docker.