Live data from Hacker News

Write tests. Not too many. Mostly integration

blog.kentcdodds.com

71–80 of 338 posts

Re: Write tests. Not too many. Mostly integration

#71

Earlier quoted context omitted.

> The biggest problem I see with people trying to write unit tests is that they don’t want to change how they write code. They just want tests for it. It’s like watching an OO person try their hardest to write OO code in a functional language. The biggest problem I see with people advocating for tests and employing TDD is that they do change how they write code to accommodate tests. This leads to inclusion of lots of…

The abstraction is consistent though, and familiarity is a good thing when navigating a codebase which has N amount of other devs pushing to it every day. I practise TDD for peace of mind - if I add new functionality to existing code I can be 99.9% sure I haven't made any regressions. When a client's system goes down on a friday, I can 99.9% guarantee it wasn't my code that is at fault. If I have to work at the weeke…

In this case, what's the difference if you write the test before or after though? You would still be covered. I don't lean in either directions in this argument, just curious to understand.

Re: Write tests. Not too many. Mostly integration

#72
Integration tests are very important and in many cases mandatory. I'd argue though unit tests with good coverage are more important. The latter helps you make sure your application has the correct output. Nothing worst than having a piece of software you think is working and silently introducing errors. The former (integration tests) makes sure your application starts and probably works in some scenarios.

With docker and containers, integration testing is easier than ever.

I've written a very simple integration testing tool (a quick hack to be honest) that executes commands, checks their exit code, the output through regexp, etc and produces a nice html report.

https://github.com/landoop/coyote

Originally written for testing some configuration tools and scripts, we quickly found a use for it for our Kafka connector collection (Stream Reactor). Our connector integration tests are at github as well:

https://github.com/Landoop/kafka-connectors-tests

Obviously unit tests make sure that the connectors work as expected. Integration tests catch simpler errors that can be showstoppers. For example an internally renamed configuration option that didn't trickle down to the configuration parser, class shadowing issues between the connectors, unexpected errors in logs that the developers should check out etc. As the tests are written by people who don't do development, they also expose problems in the documentation. In some cases they provide us an easy way to quickly run locally a connector and catch some issues manually, like extensive CPU usage or way too much logging (e.g a function with a log statement was inside a loop that run hundreds or thousands of times per second).

It gives us confidence in what we ship with every release.

Re: Write tests. Not too many. Mostly integration

#73

Earlier quoted context omitted.

The abstraction is consistent though, and familiarity is a good thing when navigating a codebase which has N amount of other devs pushing to it every day. I practise TDD for peace of mind - if I add new functionality to existing code I can be 99.9% sure I haven't made any regressions. When a client's system goes down on a friday, I can 99.9% guarantee it wasn't my code that is at fault. If I have to work at the weeke…

In this case, what's the difference if you write the test before or after though? You would still be covered. I don't lean in either directions in this argument, just curious to understand.

The difference is night and day - writing tests first means you write 'testable code' from the beginning. Following the red, green, refactor mantra means that for every change to your code, you already have a failed test waiting to pass. The result is your test cases make a lot more sense and are of a superior quality.

To liken it to something you may be familiar with - when commenting your code, do you think it's better to add comments in as you write the code? Or add in the comments at a later date after the code is all written? I'm sure you immediately know which approach results in better quality commenting, and it's the same with TDD.

Re: Write tests. Not too many. Mostly integration

#74
post #3

Good lord. Why integration tests? I think the biggest thing you can do to write more integration tests is to just stop mocking so much stuff. Okay. The biggest problem I see with people trying to write unit tests is that they don’t want to change how they write code. They just want tests for it. It’s like watching an OO person try their hardest to write OO code in a functional language. So they try to write E2E tests…

>Okay. The biggest problem I see with people trying to write unit tests is that they don’t want to change how they write code. They just want tests for it. It’s like watching an OO person try their hardest to write OO code in a functional language. I've seen what happens when a developer tries to abstract away a database in a database driven app so it can be "better unit tested". It's a goddamn mess. If your app reli…

> If your app relies heavily on using a database, your app naturally integrates with a database then it makes no sense to test without it. You are intentionally avoiding testing in a way that will pick up bugs.

Also, with Docker it's now actually feasible to automatically test against a real database at a reasonable speed. A Postgres container spins up in a couple of seconds, a SQL Server one in a little over four.

Re: Write tests. Not too many. Mostly integration

#75

Earlier quoted context omitted.

> as much as you can into static helper functions and most of the rest into dumb private stateless functions In our work we use C# and it is very hard, even next to impossible to make a static class pass a code review - given it's not for extension methods (which I hate... why not be explicit about the first parameter and stop acting as a part of the class ). They just tell us to use IoC and move to the next point. I…

Do you practise TDD? If you did a lot of this would make more sense to you. TDD is actually quite fun when you get the hang of it (less mental burden as you push all the 'intent' onto the computer).

TDD is completely orthogonal as to whether you write functional code that doesn't have a default receiver for routines, or OO code.

Re: Write tests. Not too many. Mostly integration

#76

Earlier quoted context omitted.

> as much as you can into static helper functions and most of the rest into dumb private stateless functions In our work we use C# and it is very hard, even next to impossible to make a static class pass a code review - given it's not for extension methods (which I hate... why not be explicit about the first parameter and stop acting as a part of the class ). They just tell us to use IoC and move to the next point. I…

Do you practise TDD? If you did a lot of this would make more sense to you. TDD is actually quite fun when you get the hang of it (less mental burden as you push all the 'intent' onto the computer).

I don't see why TDD requires ruling out static methods and insisting on hiding everything behind an interface. Static methods are straightforward to test, certainly more than a class with multiple dependencies which need to be mocked. Usually the complaint is about coupling when calling static methods but these can be wrapped in a delegate if required.

Re: Write tests. Not too many. Mostly integration

#77

Why does everyone rethink a working strategy. Write lots of unit tests that are fast. Write a good amount of integration tests that are relatively fast. Write fewer system integration tests that are slower. The testing pyramid works. He even talks about it in this post, and then ignores the point of it. You write lots of unit tests because you can run them inline pre-commit or in a component build. If you integration…

>Why does everyone rethink a working strategy. Write lots of unit tests that are fast. * Because I want to avoid writing more code than necessary. * Because I want to avoid writing tightly coupled code. * Because I'd rather have a test that takes 2x longer and catches 5% more bugs. Premature optimization and all that.

Lots of unit testing can cause tightly coupled code, if the units are too small and/or against internal APIs: The tests are tightly coupled to a piece of code which should have been able to change freely.

Re: Write tests. Not too many. Mostly integration

#78

Earlier quoted context omitted.

Do you practise TDD? If you did a lot of this would make more sense to you. TDD is actually quite fun when you get the hang of it (less mental burden as you push all the 'intent' onto the computer).

I don't see why TDD requires ruling out static methods and insisting on hiding everything behind an interface. Static methods are straightforward to test, certainly more than a class with multiple dependencies which need to be mocked. Usually the complaint is about coupling when calling static methods but these can be wrapped in a delegate if required.

Simply because you can't mock the static dependency, therefore that method is now dependent on the static class and you don't have any control over it. This is problematic - what if at some point later another developer adds a database call into the static method to do some logging? Now your testing will dirty whatever database you're using, as well as run 10x slower - and yet the test will still pass and everyone will be none the wiser as to what happened.

If you start using a custom delegate solution, then your code is not consistent with everything else that uses DI, making it harder to understand. I can understand interfaces are annoying when navigating code, but the IDE still helps with that even if it is a few more button clicks, and the pros outweigh the cons.

Re: Write tests. Not too many. Mostly integration

#79

Earlier quoted context omitted.

people ... don’t want to change how they write code. They just want tests for it Have you considered the possibility that those people are right? That's a reasonable conclusion to make if you are seeing lots of otherwise smart people that share an opinion that disagrees with yours. There are lots of valid reasons to change the style in which you write code. In my mind, fitting somebody's fad testing scheme is not one…

Usually splitting out into interfaces is done in static languages as that's the best type-safe way to do things. It's not a fad, it's been like that since the beginning.

There is absolutely no reason (except to fit into a particular pattern of testing) to turn everything into an interface[1]. That has nothing to do with type safety.

[1] Obviously some things do make sense to put behind interfaces, but I find that most Java developers go interface crazy and the code ends up being an unreadable mess.

Re: Write tests. Not too many. Mostly integration

#80

Earlier quoted context omitted.

> The biggest problem I see with people trying to write unit tests is that they don’t want to change how they write code. They just want tests for it. It’s like watching an OO person try their hardest to write OO code in a functional language. The biggest problem I see with people advocating for tests and employing TDD is that they do change how they write code to accommodate tests. This leads to inclusion of lots of…

The abstraction is consistent though, and familiarity is a good thing when navigating a codebase which has N amount of other devs pushing to it every day. I practise TDD for peace of mind - if I add new functionality to existing code I can be 99.9% sure I haven't made any regressions. When a client's system goes down on a friday, I can 99.9% guarantee it wasn't my code that is at fault. If I have to work at the weeke…

Exactly this. Confidence is everything.

I can actually write entire features with appropriate test coverage from the ground up and they work first time and have close to zero defects in production.

It's amazing when you spend 5-6 days writing code that does nothing and at the last moment, everything slots together with a few integration tests and wham, feature done. Not talking trivial stuff here either; big integrations across several different providers/abstractions, bits of UI, the lot.

You see a lot of people arguing against this but I'm going to be honest, they churn out a lot of stuff that doesn't actually work.

Post reply on HN