Live data from Hacker News

Testcontainers

testcontainers.com

211–220 of 260 posts

Re: Testcontainers

#211
post #200

Earlier quoted context omitted.

Their details might be wrong, but were perhaps not always wrong. Either way, the spirit of their argument is clearly not wrong.

> the spirit of their argument is clearly not wrong. Uh, the jury’s out on that seeing as how the parent didn’t give any specifics other than some hand waving about “issues with other containerized workflows.” OK, elaborate on that please, otherwise the parent isn’t really making a valid point or may be misinformed about the current state of Testcontainers w.r.t. to these vague “other containerized workflows.”

yet people are showing up here and agreeing completely. So, it seems common enough not to need elaboration.

Re: Testcontainers

#212
I'm surprised this is getting so much attention. I thought this just standard practice at this point? If you use things like Gitlab CI then you get this via the `services` in your pipeline. The CI job itself runs in a container too.

I use a very similar thing via pytest-docker: https://github.com/avast/pytest-docker The only difference seems to be you declare your containers via a docker-compose file which I prefer because it's a standard thing you can use elsewhere.

Re: Testcontainers

#213

Earlier quoted context omitted.

Which is a perfectly fine counter-argument if you are, in fact, not going it right. If you say you're doing continuous deployment because you deploy every Tuesday evening, it's perfectly fair to point out that that's not continuous deployment. Of course, you should follow it up by explaining why as well, but many companies don't actually follow the agile principles.

This is a digression from the original topic, but my criticism of agile is in fact that nobody is doing it right. If the majority of companies that attempt it end up just wasting extra time, the process itself is broken.

I don't think you can claim that. It's the fate of most popular systems. they end up being poorly explained in elevators or adopted based on a blog article rather than investing the few hours or days or weeks to understand what made the process originally successful. It's so common we have a term for it: cargo culting. I don't think you can fault agile for the tribally-spread BS most places do today where points == hours. If anything, you can maybe fault it for seeming a bit too familiar and simple when there are a few important nuances.

Re: Testcontainers

#214

Earlier quoted context omitted.

What if you are unit testing something that is dependent on infra?

Typically you mock them in unit tests.

If the "thing" is a database, for example, then the way to mock it is to bring up a database container and load it with dummy data.

Re: Testcontainers

#215
post #60

Earlier quoted context omitted.

This makes no sense tho. Simple example, your code needs to reach into Cosmos / DynamoDB, why mock this service when u can get so much wrong by assuming how things work?

Mocking doesn't mean you have to reimplement the fully featured service. In the simplest form your internal library which calls out to Cosmos is mocked, the mock records the request parameters and returns ok, and the test verifies that the expected data was passed in the call.

Then you're testing the implementation and need to change the test and mocks every time the implementation changes.

Making stuff quicker is a good reason to mock stuff. So is not hitting real network services. But, in all cases, the best thing is to avoid mocking if possible.

Re: Testcontainers

#217
post #190
post #139

Earlier quoted context omitted.

This advice is so misguided that I'm concerned for our industry it's getting so much traction. > You really want to avoid testing implementation details because it doesn't give you very much confidence that your application is working and it slows you down when refactoring. You should very rarely have to change tests when you refactor code. Unit tests don't need to test implementation details. You could just as well…

in a perfect world each unit would do the obvious thing without many different paths throught it. The only paths would be the paths, that are actually relevant for the function. In such a perfect world, the integration test could trigger most (all?) paths through the unit and separate unit-tests would not add value. In this scenario unit tests would not add value over integration tests when looking for the existence…

> in a perfect world each unit would do the obvious thing without many different paths throught it.

I don't think that's realistic, even in an imaginary perfect world.

Even a single pure function can have complex logic inside it, which changes the output in subtle ways. You need to test all of its code paths to ensure that it works as expected.

> In such a perfect world, the integration test could trigger most (all?) paths through the unit and separate unit-tests would not add value.

This is also highly unlikely, if not impossible. There is often no way for a high-level integration test to trigger all code paths of _all_ underlying units. This behavior would only be exposed at the lower unit level. These are entirely different public interfaces.

Even if such integration tests would be possible, there would have to be so many of them that it would make maintaining and running the entire test suite practically unbearable. The reason we're able and should test all code paths is precisely because unit tests are much quicker to write and run. They're short, don't require complex setup, and can run independenly from every other unit.

> But: In a bigger project you don't only want to know "if" there is a problem, but also "where". And this is where the value of unit tests comes in.

Not just in a "bigger" project; you want to know that in _any_ project, preferably as soon as possible, without any troubleshooting steps. Elsewhere in the thread people were suggesting bisecting or using a debugger for this. This seems ludicrous to me when unit tests should answer that question immediately.

> Also you can map requirements to unit tests, which also has some value (in some projects at least)

Of course. Requirements from the perspective of the API user.

> now that I think about it, you can also map requirements to e2e tests.

Yes, you can, and should. But these are requirements of the _end_ user, not the API user.

> That would probably even work much better than mapping them to unit-tests would.

No, this is where the disconnect lies for me. One type of testing is not inherently "better" than other types. They all complement each other, and they ensure that the code works for every type of user (programmer, end user, etc.). Choosing to write less unit tests because you find them tedious to maintain is just being lazy, and finding excuses like integration tests bringing more "bang for your buck" or unit tests "slowing you down" is harmful to you and your colleagues' experience as maintainers, and ultimately to your end user when they run into some obscure bug your high-level tests didn't manage to catch.

Re: Testcontainers

#218
post #217
post #190

Earlier quoted context omitted.

in a perfect world each unit would do the obvious thing without many different paths throught it. The only paths would be the paths, that are actually relevant for the function. In such a perfect world, the integration test could trigger most (all?) paths through the unit and separate unit-tests would not add value. In this scenario unit tests would not add value over integration tests when looking for the existence…

> in a perfect world each unit would do the obvious thing without many different paths throught it. I don't think that's realistic, even in an imaginary perfect world. Even a single pure function can have complex logic inside it, which changes the output in subtle ways. You need to test all of its code paths to ensure that it works as expected. > In such a perfect world, the integration test could trigger most (all?)…

> Even if such integration tests would be possible, there would have to be so many of them that it would make maintaining and running the entire test suite practically unbearable. The reason we're able and should test all code paths is precisely because unit tests are much quicker to write and run. They're short, don't require complex setup, and can run independenly from every other unit.

I think having a good architecture plays a big role here.

Re: Testcontainers

#219
post #60

Earlier quoted context omitted.

Mocking doesn't mean you have to reimplement the fully featured service. In the simplest form your internal library which calls out to Cosmos is mocked, the mock records the request parameters and returns ok, and the test verifies that the expected data was passed in the call.

Then you're testing the implementation and need to change the test and mocks every time the implementation changes. Making stuff quicker is a good reason to mock stuff. So is not hitting real network services. But, in all cases, the best thing is to avoid mocking if possible.

Why do you care how Cosmos or DynamoDB or any other dependency is implemented? You only need to mock the interface to these services. Their internal code can change every day without affecting your tests.

And if you want to catch potential changes in Cosmos that modify the behavior of your own service, that isn't the purpose of unit tests.

Re: Testcontainers

#220
post #201
post #135

Earlier quoted context omitted.

I've heard this aversion to unit tests a few times in my career, and I'm unable to make sense of it. Sure, integration tests "save" you from writing pesky unit tests, and changing them frequently after every refactor. But how do you quickly locate the reason that integration test failed? There could be hundreds of moving parts involved, and any one of them malfunctioning, or any unexpected interaction between them, c…

> Sure, integration tests "save" you from writing pesky unit tests, and changing them frequently after every refactor. The DB migration has "ADD COLUMN rateLimit INT" The application class member is annotated with "@Column(name=”ratelimit”, nullable=true)" The failure is at the interface between the app and the DB. What testcontainers does is allow you to write a quasi-unit test (not a truly full-blown integration te…

That's an _integration_ failure. We're talking about testing two entirely different things here. Of course you shouldn't expect to test integration scenarios in unit tests.

But you also shouldn't expect to test all unit scenarios in integration tests. This is what the "trophy testing" model advocates for. That somehow unit tests are not needed if you have thorough integration tests, which is entirely false.

They test the application at different layers, because they're meant to ensure behavior to different types of users. They're both useful for catching bugs and unexpected behavior, and they're meant to complement each other.

Post reply on HN