Resources Blog Wicked Good Development Episode 31: Testcontainers ...

Wicked Good Development Episode 31: Testcontainers with Oleg Šelajev


Ready to take a dive into the world of Testcontainers? Join Kadi Grigg and Sonatype Developer Advocate Jamie Coleman as they sit down with the one and only Oleg Šelajev of AtomicJar, Inc., for an episode packed with insights and laughs.

Together, they'll delve into the world of Testcontainers and uncover the secrets behind these powerful tools that have revolutionized the testing landscape. From the origin of Testcontainers to the crucial importance of reliability in testing, they'll cover it all and so much more.

Listen to the episode

Wicked Good Development is available wherever you find your podcasts. Visit our page on Spotify's

Show notes



Relevant links


Kadi Grigg (00:11):
Hi, my name's Kadi Grigg, and welcome to another episode of Wicked Good Development, where we talk shop with OSS innovators, experts in the industry, and dig into what's really happening in the developer community.

Jamie Coleman (00:21):
Hi everybody. My name's Jamie Coleman, and I will be your co-host today. Who am I? So, I am a developer advocate for Sonatype. I work on supply chain security, etc., with a lot of experience in Java. So, I used to work for Java Runtime and a little bit of experience in Testcontainers. This is why I'm the co-host today.

Kadi Grigg (00:42):
So, as Jamie alluded to, today's episode is all about Testcontainers. And who better to speak with us today than Oleg Šelajev. So, Oleg, before we get into today's conversation, do you mind giving the listeners at home a little intro of who you are and what your interest is in Testcontainers?

Oleg Šelajev (00:58):
Hi, I'm very happy to be here. Hi, Kadi. Hi, Jamie. Hi, everyone listening to us. My name is Oleg. I work as a developer relations person on the team AtomicJar. We are a fairly small startup of less than 30 people founded by the maintainers of the Testcontainers libraries. It happened a few years back in 2001-- oh no-- 2021. Sorry, bad with numbers. That's what booted me from engineering to devrel. So, the Testcontainers libraries are open source libraries that simplify testing of your applications. And we're going get into that later. But in general, it's a very popular approach of how to do tests. And I feel that testing is essential for all developers. There are no projects that could be better if they didn't have tests.

Oleg Šelajev (01:56):
So, this is the topic that is very, very dear to me and I love it here. And before that I worked at various other companies in the projects in open source. And my personal experience with Testcontainers goes way back to 2015 or something to the very beginning of the existing of the Testcontainers Java library, which was the first in the bunch. And yeah, and that's how I sort of stumbled into this current position. And I love it, because I feel it's very important. I feel like any developer that I meet, they have something to teach me about their setups, about how they do tasks. And I feel like very often I have some experience to share with them. Because as a developer relations person, this is what I can do best-- where I can provide the most value is to syndicate and aggregate the information that I get from many developers that I talk to in-person or online all over the world. And then pass that information in some sort of-- in a succinct way to the next people that I talk to.

Kadi Grigg (03:07):
Well, thank you for being here, Oleg. Let's dive in. So, let's just start with the basics. For those of us at home who may or may not have heard of Testcontainers before, this could be a new word for them. What is a Testcontainer?

Oleg Šelajev (03:25):
So, Testcontainers is open source libraries that allow you to run your unit test with real dependencies. So if your application requires any third-party services to run-- it could be a database, or it could be a message broker, or it could be for the test, you need some sort of other infrastructure like cloud technologies that you're using, or it could be literally anything else besides the application that it needs to run-- Testcontainers gives you the flexible programmatic API to create and manage instances of those services in containers. That's the name. This is very, very useful specifically for your testing scenarios where your application would like to control by itself what environment it runs in. Because no one knows better what the application needs for running than the application with the code itself.

Oleg Šelajev (04:19):
So, Testcontainers gives you the way in the test to declare that, "I would like to work with a database, say, I would like a Postgres here," and then gives you the API to instantiate, configure that instance of Postgres, and then feed that information where that is located back into tests. So, your application can run against the real database, and it avoids a number of issues like incompatibility with various in-memory solutions running tests against not the versions of the software that you run in production because the environment is managed by tests themselves, like it's very, very easy to, for example, paralyze the tests because there is no contention on the shared instances that you might have otherwise. And in a nutshell, when you use Testcontainers for your test, you get the reliability of integration tests that run with real technologies.

Oleg Šelajev (05:16):
But the user experience of the test is of a unit test, because the configuration for that is standalone and isolated within the code of the test. You can run them in isolation. You can literally in your IDE click "run" on a single test method, and it'll run. And it'll run the same way. This is because the environment is fully controlled programmatically, it'll run the same way in all environments. So, it'll run the same way in CI, and it'll run the same way on your local machine or on somebody else's machine because the environment is created on the fly just for the test. This gives you incredible confidence in your test suite because, well, real technologies, your application runs as if it would run in production, but it also gives you the developer experience where you can very easily reproduce the issues.

Oleg Šelajev (06:05):
So, that means that it's very easy not to get in this pit of despair over the tests-- when you don't like to do something, you naturally tend not to do that. And developers are no exception, especially given that laziness is a virtue. And then there is always fun things to do, and there are also less fun things to do in the day-to-day job. When something becomes less fun, you tend to postpone it or not work on it that much. So, testing is very often, I feel like that could become that. If you don't have great confidence in your test suite, not just in individual tests, but in the suite in general, you tend to ignore some factors.

Oleg Šelajev (06:53):
You start to pile up tests. You don't like it. With Testcontainers, what I find very often is developers like how it feels to work with the tests and also have higher confidence in that actually those tests matter. So in a nutshell that is the approach of Testcontainers. Real dependencies inside your unit tests. The best of both worlds.

Jamie Coleman (07:18):
That's awesome.

Oleg Šelajev (07:19):
And of course when I said libraries there are different implementations of Testcontainers' approach in different languages. It all started something like eight years ago with Testcontainers Java, and now we have Testcontainers Go for Golang, Testcontainers .NET, Testcontainers Node.js, there is Testcontainers Python, Testcontainers Rust. I think very recently, one of the newer implementations is Testcontainers Haskell believe it or not, which is, I find personally that my main experience is Java.

Oleg Šelajev (07:51):
So, I find it very interesting when developers in other language ecosystems have similar problems, and then they find a similar solution to be very useful. So, there is-- whatever popular language you're working in-- there is an implementation or maybe if there is not, maybe you should be the one to start it. If you are into open source, well, how hard can it be? Certainly at AtomicJar, we would love to support and help all the implementations. So, if you're working in a language that doesn't have it-- Testcontainer Swift or something-- then yeah. That was off-topic. I didn't plan this.

Kadi Grigg (08:32):
Is there a reason why they picked certain languages? Is it just due to popularity or someone wanted to work on it?

Oleg Šelajev (08:39):
I think normally it's just because people come from the ecosystem where Testcontainers libraries are popular and used very much and then theyfor other reasons, they switch languages and then they feel the void. So, I know that because the current maintainer of the Testcontainers Go-- Manuel de la Peña-- he said that his experience was Java. And he was happy, and then he had to switch to Go. And he felt that, "Where's my Testcontainers?" So, he started-- maybe not Go, maybe I'm missing something-- but certainly some implementation started because just people felt lack of the library, and they were like, "It was so convenient in Java. I should start the version." I think for sure the .NET version was started like this. Andre, who's the current maintainer, I think he wrote an article when he joined AtomicJar that, yeah, he started because he was put into a legacy project, and he needed tests and then he was like, "Yeah, this is the best approach to tests that you can trust." And yeah, that's how it happened.

Jamie Coleman (09:51):
That's pretty awesome. So, my experience has mainly been Java with Testcontainers. And from what I've experienced, it's been pretty easy to implement. I mean, one of the main things I love about Testcontainers is I can take a normal JUnit test and very easily turn it into-- utilize Testcontainers with very minimal additional code. But how different is the experience comparing to different languages? Because of course my experience is only in Java. Is the experience of getting Testcontainers working with different languages similar or a different approach?

Oleg Šelajev (10:22):
It is very similar. So, the libraries try to offer idiomatic API for the language. And there are of course some differences in the underlying implementation and also some differences in the level of maturity of the certain-- maybe not the main core APIs, because they are a little bit easier to just use one version as a template. And recreate in a different language but in some particular configurations. For example, in Go, there is no notion of a class pass, right? Your application is compiled to Refinery. And when you run your tests, the tests are also an application that get compiled, and they get executed. So, there is no notion of class pass. So, for example, some API where in Java we allow dealing with the class pass or it just doesn't make sense.

Oleg Šelajev (11:12):
And then there are some implementation differences that, for example, the Go version can rely on the actual Docker libraries to talk to the Docker runtime. And in Java, we use a Docker Java, which is another open source project that allows us to talk to Docker in a compatible way and stuff like that. So that's one. But the core is very similar. You add the depend-- you are the library, and then you add the module. This is one of the great things about Testcontainers is that there is a low-level API that allows you to deal with the containers. So, you can say, "I would like a container that will run that image and would like to configure it expose certain ports to access it." Maybe copy this configuration file into that location in the container before you start or after you start execute this command. And those are the low-level API dealing with the containers and you can build anything with that.

Jamie Coleman (12:14):
That's-- generally my experience is with the low level APIs.

Oleg Šelajev (12:16):
But because it's a library and it's old code, you can build abstractions that will be suited specifically for you or your team or specifically for a given technology. For example, if you have an application that needs to work with Kafka, it might be possible that you would know how to run Kafka in a Docker container. But it's not necessary. In the Testcontainers ecosystem, for example for Java, you have the library that is Testcontainers Kafka module. And there are modules for most popular technologies like Elasticsearch, all the databases, Postgres, Kubernetes cluster. If we're talking about Kafka, then we have a module for Redpanda, which is a different implementation of Kafka. Well, it's a different Kafka implementation. And then what you do as an end developer, you don't actually say, "Oh, give me-- and run that Kafka container and configure it in this way."

Oleg Šelajev (13:10):
You just say, "New Kafka container." And somebody has thought about how to run Kafka in a Docker and provided you with this abstraction that you can use in your code. And that serves two very giant purposes. And I think this is one of the biggest reasons why Testcontainers became as popular-- it's because you don't have to know how to configure things yourself. And you don't need to do that from scratch all the time. So, there are levels of abstractions, and you get the ecosystem of the modules that covers all possible technologies. But the second thing is, because it's the abstraction in the code, it can offer the API to work with that technology in the technology-specific manner. For example, if you work with the database, there are common things that you would like to do with the database.

Oleg Šelajev (13:59):
For example, you would like to get the, in Java, get the JDBC URL or the name of the database schema or the name of the user or password for the credential to access the database. You can maybe do that and configure it on the container level. And say: "Oh, those are my environment variables. I will use my static field here in Java to hold my username, and I will pass it to the container and hold it." But you can also reverse this and have the Testcontainer module implementation, take care of those details. And then just ask from the container, "Give me the username that I can use to authenticate to the database." Because the database is created dynamically, the Java object that you operate in your code, it has all the information about that.

Oleg Šelajev (14:52):
So, you can use the API that are high-level and technology-specific, either like the actual technology, like a database or like for Kafka, you can ask for the bootstrap servers, which is the URL that you need to access Kafka from your application is called Bootstrap servers. And then you can just have a Java method, which works great. Because why? Because it allows you to explore what is possible to do with the modules and containers from your IDE. You don't have to know what you can do with Kafka or any other technology. You don't have to even read the documentation. You don't have to go on the website and spend like an hour reading about different things. What you can do: You can type (dot) in your IDE and your IDE will offer everything that you can do with the thing.

Oleg Šelajev (15:43):
Because it's all encoded in the methods and in the API. So, it works great for developers because, let's be honest, very many people don't like reading documentation. And if it's not in your IDE, it doesn't exist. Because it's also like-- I'm just saying, I'm not judging. I myself am the same. Very often when I have a problem, it's easier to build a workaround from crutches and a little bit of glue here and there and then it's ugly, but it works. It's easier to do that, because I'm all in the process of tinkering. And it feels like work. It's much easier to do than to go and read the docs how to do it the proper way. So, having that proper way encoded in a way that it's right in your-- like at your fingertips in the IDE is massive, massive, massive for a library. And I think Testcontainers got it right. And I think we are seeing the popularity, which is the part of that.

Jamie Coleman (16:41):
That's awesome. I mean, again, that's one of the reasons I got involved, and I really like Testcontainers. Just the ease of use of getting started with the modules that are already there just makes just using it a delight, to be honest. So, moving on to a related question something I've never used with Testcontainers are the cloud modules such as the Google and Azure modules. What do they do? Because I've never actually played with the cloud modules myself.

Oleg Šelajev (17:08):
This is interesting. So, there are different implementations of how Testcontainers modules help you test applications that work with cloud technologies. So, I think the most popular one is the LocalStack module. Localstack is a compatible implementation of AWS, which is what the company LocalStack that provides the Docker images with LocalStack would they say that. And in my experience, it's very compatible. But what it gives you-- it gives you a Docker image that you can start as a container. And it will give you a local implementation of AWS, of the functionalities of AWS. So, you can have the services, for example, S3 or DynamoDB or Lambda, and you can enable those and then you can test your application with that LocalStack running somewhere in the container, and your application will be no wiser that it doesn't work with the real AWS. So, the same way as the local container with, let's say an Oracle database properly emulates the Oracle database because it is a compatible inclination. The same way LocalStack, for example, works on AWS and for Google Cloud we have the, in Java, Testcontainers implementation. We have a G-cloud module, and it works by working with the emulators that Google provides for their services, like Bigtable and Spanner or something else, I didn't work with that. And with Azure, there's the Cosmos DB implementation, which is what people mostly are testing via Testcontainers. I think it's a very, very convenient way, because it simplifies the testing against the particular cloud technologies.

Oleg Šelajev (19:05):
So, I think the cloud providers could really think about maybe investing a little bit more resources into those emulators or compatibility tools, because they don't need to provide the runtime guarantees of the actual cloud, because it's a test. If it goes down under extreme conditions, maybe it's not a big deal. You don't have to replicate it against multiple data centers. You don't have to protect it against natural disasters or anything. So, it just needs to work and be compatible at the functional level. And then developers in all the languages can use the same approach they know and love for testing against other technologies for your particular cloud. So, I think it's very, very useful, and it's certainly very good for-- it works very, very well for LocalStack and AWS and others. I think they're fairly popular test containers modules. And yeah, so that is how you test cloud technologies.

Jamie Coleman (20:08):

Kadi Grigg (20:09):
So, you've talked a good bit about what it's like from the development perspective, and how it's very easy to have all this power at your fingertips readily available. What is it like from the security standpoint? How does security work with integration testing?

Jamie Coleman (20:25):
In particular, Testcontainers?

Oleg Šelajev (20:27):
Yes. That's a good question. That's actually-- it's not something that maybe many, many people think about. But one of the essential-- again, my personal opinion-- one of the essential parts for having the application that you trust-- not trust-- the process of development keeps security in mind is to have a very good automated test use that you trust. Because in case something goes wrong-- and something will go wrong-- there will be like a Log4j-like library exploits that will definitely be a problem for you. And they will be unexpected. That's the nature of security vulnerabilities. They are unexpected. Eventually. So, to have reliable pipelines for security for tests means that you can get the fixes that other people maybe smarter than you created.

Oleg Šelajev (21:24):
And then you go through any sort of the security-related tooling that tells you maybe it's not unexpected. Maybe it's not a Log4j where the whole world breaks at a moment's notice and everyone scrambles. Maybe it's just a regular security update of the application during the cycle. And then, but that also means that you need to update your applications to new versions to which some tools will tell you, "Oh, that version has vulnerabilities." You need to upgrade to the next one or somehow. You upgrade as a good citizen. Now the question is how do you get that from the source code that you have into production? Because technically what you need to upgrade is your production environments. Because that's where vulnerabilities are critical, but the only way to upgrade that is to upgrade your source and then do the deployment through all the pipelines.

Oleg Šelajev (22:22):
So, if your deployment is not automated, if the deployment is-- not the deployment, the whole pipeline-- if the whole pipeline bottlenecks on certain things, for example, you need to get it into staging and you need your QA team to spend two weeks verifying the changes, that will be a bottleneck. If your deployment pipeline is two weeks, you cannot react to security vulnerabilities faster than in two weeks. This is where the tests come in. If your integration tests are the metric which you trust to determine whether a certain thing passes the quality, that means that your pipeline can be much faster. That means that you can get your security advisory in action. And you update your dependencies and then you run the tests. And if the tests are green, it's go, go, go time. If the test are not green, you cannot release, but you have to fix it in development because you cannot fix it anywhere else. So, and then that shortens the time from source to production and that positively impacts your security.

Jamie Coleman (23:36):
That's cool. So, simply by using Testcontainers and getting that kind of dev parity allows you to essentially get stuff into production quicker and as a result allows you to have better security in your application. That's cool. I like that.

Oleg Šelajev (23:51):
Yes, I think that summarizes it. Well, having the automated tests that you trust helps you shorten that thing. And Testcontainers is one way to organize your tests to get that reliability,

Jamie Coleman (24:09):
It sure has helped me, because it just gives me a bit of peace of mind that when I put this into the pipeline that it's got more of a chance of passing, because I've done the right tests locally on my machine as opposed to waiting for it to get into that kind of environment with different variables. So, I think that's really cool. Definitely, definitely a good way to improve organization security.

Oleg Šelajev (24:30):
And it's not just the libraries that you upgrade. So, from the security point of view or specifically the supply chain security libraries are what we talk the most about. Because your code you control, and those are control changes and you can impact them maybe somehow. You can be like, "Oh, just write secure code--duh." But with libraries, you don't control them. You get a new number and then you upgrade it, and then you might not necessarily even know how much that library impacts your application, because it can work in mysterious ways. Especially in such a dynamic runtime as Java. But you also update your services. I think just today I saw a tweet from Julien Dubois at Microsoft, and he was a little bit praising Testcontainers as an approach, because they were trying to upgrade, I think MySQL or something from one version to another, and there were some changes in the implementation of the database that impacted something.

Oleg Šelajev (25:40):
And then because he said that their initial tests was H2, which is the in-memory relational database that he uses in Java. And then of course, the test passed on H2, because it doesn't-- there are no differences. It's a mock. You don't control the compatibility of your in-memory implementation and the actual real software that you run in production. And then if you change and run the test against the real proper versions of MySQL that you want to, for example, via Testcontainers, you can see the differences. And with Testcontainers, because literally you can run the same test with say, MySQL 5, MySQL 8, Postgres 15. And the difference is just literally like a string that you give to the Testcontainers module saying, "This is my Docker image that I want to run against."

Oleg Šelajev (26:36):
You can very easily run your test suite with different inputs and say, "Does my application work on MySQL 8 the same way as it works on MySQL 5?" So, if you need to upgrade your services in the production environment, you can still verify you have the compatibility, which is very many-- it might be not what application projects are doing, because maybe you upgrade your services very infrequently, but this is what made Testcontainers the go-to choice for very many projects that work with the vendor technologies. If you are providing, say a database driver, that needs to work or some optimization to the database driver, for example, it needs to work with multiple different databases. How do you do that? You can create those environments manually, and then it'll be slow and painstakingly fragile. Or you can just have different implementations with Testcontainers, which then in the code you control that. So there is a certain flexibility of the approach, not just even the implementation of the approach that allows you to build very, very cool things.

Kadi Grigg (27:52):
So Oleg, we've talked quite a bit about a few different things here today, and it just seems like there's so many different use cases for Testcontainers and things it can do. And Testcontainers is about to hit its 8th birthday at some point this year. How can newcomers get involved with Testcontainers? What advice would you give to them for people who are looking to get involved or better understand them?

Oleg Šelajev (28:15):
This is a great question. It's an established, mature open source project. So, there is quite a bit of materials everywhere. I think we are currently working at AtomicJar, because we would like to simplify and make the onboarding of new developers as easy as can be. So, we are working on a little bit of a guides initiative that we're going to roll out starting from the very beginnings. So, there is documentation, and for the Java version, you can go to or for any other language, including Java, you can go to and pick the language inclination that you want and get to the docs. But there will be also the guides that can guide you through this. They probably will also live on testcontainers.Com, so stay tuned for that.

Oleg Šelajev (29:06):
But one essential, maybe essential, resource that not many people maybe understand, and maybe it's not for the newcomers, because it's a little bit deeper level. But this is something that I use very often and I hoped more people can learn about that. For the particular technologies, when you master the core API, which are not particularly large surface of API, you just need to understand abstractions, like generic container and that's anything in the container that is it. For the particular usages of the modules, which is where you would like an idiomatic way how to use my Kafka or something, then the documentation we will improve with it, and we are working on it, and it's going to be better. But one underappreciated resource is the open-sourceness of the libraries. There are-- you don't just have the implementation of that Kafka module.

Oleg Šelajev (30:09):
You also, what you have in the open source in the GitHub repository, you also have the tests for that module, and tests show you exactly how to use that. So, for example, once in a while I need to spin up Elasticsearch container. And because I do it so infrequently, I always forget what exactly I need to do. Or how exactly I work it back or what it is that they need to pass back into my application to configure Elasticsearch. And again, I could read the documentation, but I just go into the Testcontainers Java Library on GitHub, I open the Elasticsearch module, I go into the tests, and right there it looks at me how exactly I instantiate the Elasticsearch container, what exactly I need to pass in, and then what are the options to make it work.

Oleg Šelajev (31:00):
And from there it's-- you have the basic thing working. And then it's much easier to tinker to do exactly what you want to do for your test. But I think it's a very underappreciated way of getting the examples. And of course-- besides, if you like typing, and if you're good at typing, then what you can do is you can go to our Testcontainers Slack workspace and just hang out there with other people who use Testcontainers and ask questions. The maintainer-- well, we are there, the maintainers of the languagesnot just the ones that work for AtomicJar, but just in general, because the implementations of Testcontainers libraries are community-driven. So, there are maintainers who are outside and don't work at AtomicJar, even though quite a bit of maintainers do work at AtomicJar currently, which I feel is a great way to give back-- their main focus is working on the open source libraries, so it's a good thing to give back to the open source. But you can just-- what I want to say, you can join the Slack channel Slack workspace, you can ask questions, and it's not just us or the maintainers, but there are also other people that can help you with the particular questions that you have. And most probably there are people that run similar setups to yours. For example, the same CI provider that has the particular ways of working with the Docker environment that they have or something like this. And then you can ask, and there are people who can help, and that is one of the best ways to get help if you want to just have an interactive discussion.

Jamie Coleman (32:42):
I can definitely testify to that. Whenever your Testcontainers, it definitely helped me looking at people's setups that are very similar configurations to mine. Again, not identical, but it allowed me at least to create a kind of bare bones template to get started and then just tweaking it to my configuration. So, that's very definitely good advice.

Kadi Grigg (33:02):
Alright, Oleg, so last question for you. It's kind of a two-parter. One-- actually it's Jamie's question. So, I'll let Jamie ask his, and then I'll ask mine.

Jamie Coleman (33:12):
So, yes, my first question-- my question is, why do you only use a capital T in the name of Testcontainers? It's something that's caught me up quite a few times with presentations and things like that. And I'm just curious as to why you went down that naming convention.

Oleg Šelajev (33:27):
That's a great question. Everyone gets it wrong. So, there is one way to write Testcontainers, and the only capital letter there is T. It was set in stone many, many years ago. There was a-- I think there was a poll in the GitHub Issues. People voted. The maintainers chose, and it's that. And everyone gets it wrong once in a while. And then I've seen people do different things like putting spaces in that word, or making two words, or capitalizing C, or just misspelling containers because it's-- apparently it's a long word, so it's easy to swap the letters. So it's just a historic reason. The name was chosen like that. It's like there is space in Red Hat. That's how it is. Yeah, today you learned.

Jamie Coleman (34:23):
That is a really, really good answer. And it is just a testament to the fact that it's a completely community-driven open source project. The fact that you had a poll to ask the community what it should be called. So, that's amazing.

Oleg Šelajev (34:36):
But also, don't be hard on yourself. At one conference, I will not shout out the conference because I did a presentation and I had Testcontainers written with capital C on the title slide. And naturally somebody took a photo of that and posted on Twitter being like, "I'm going to enjoy this presentation now." And Kevin Wittek, who is the maintainer of Testcontainers Java and my colleague he was sending me Slack messages like, "Oleg, is this some sort of sick joke? We have enough people misspelling it as it is without you going at conferences in front of hundreds of people misspelling that as well."

Kadi Grigg (35:21):
You're just making sure people were paying attention. It was just a little puzzle.

Oleg Šelajev (35:25):
Kept my job. All good. It's-- yeah but there is a proper way to write it: lowercase c. If you didn't catch it, lowercase c.

Kadi Grigg (35:36):
So, last question is, given all that we've talked about today in this conversation, is what do you think wicked good development looks like to you?

Oleg Šelajev (35:45):
Alright wicked good development. So, I know some of the brilliant engineers, and they can create very complex applications, and they make it seem easy. Or they can turn out libraries, not just like "Hello Worlds" but like some actual libraries that people start using, and even the original idea creator moves on, the library sort of lifts. And then very often what they have is they have this mindset where the code that they do, that they write, it doesn't have to be perfect, but it has to work. Because it's very easy to try to make the code perfect, but it has to work. And there is two definitions of working. One is that it passes the tests, and the other is that it is useful for people in reality. It's actually useful in its final production shape. But tests are even-- it's not more important, because the actual final useful is more important, but tests allow you to move fast without breaking things. And that makes you very, very productive. So, you don't have to practice test-driven development. I will not judge you. But if you have the tests in your pull request before your reviewer comes to you with, "Where are the tests?", then you are a wickedly good developer.

Kadi Grigg (37:25):
That's a great answer. Well, thank you so much for taking the time to chat with Jamie and I today, Oleg. We'll make sure we put those resources in the transcript for the blog.

Oleg Šelajev (37:33):
Thank you for having me.

Kadi Grigg (37:38):
Thanks for joining us for another episode of Wicked Good Development, brought to you by Sonatype. Our show was produced by me, Kadi Grigg. If you value our open source and cybersecurity content, please share it with your friends and give us a review on Apple Podcasts or Spotify. Check out our transcripts on Sonatype's blog and reach out to us directly with any questions at See you next time.

Picture of Kadi Grigg

Written by Kadi Grigg

Kadi is passionate about the DevOps / DevSecOps community since her days of working with COBOL development and Mainframe solutions. At Sonatype, she collaborates with developers and security researchers and hosts Wicked Good Development, a podcast about the future of open source. When she's not working with the developer community, she loves running, traveling, and playing with her dog Milo.