This is my version: Don't stop writing tests. Not until 100% coverage. Mostly unit. Especially if you are developing a library. An untested code branch is a ticking time bomb, in my book. An application for the end users indeed does benefit from integration tests, a lot. The problem is running them efficiently. If they take an hour to run, nobody will care to analyse them.
Write tests. Not too many. Mostly integration
111–120 of 338 posts
Re: Write tests. Not too many. Mostly integration
#112Earlier quoted context omitted.
>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.
I would recomnend not optimizing for less code. Optimize for reading less code. Unit tests actually tend to favor highly uncoupled code while integration seem to favor more coupling with e2e favoring the most coupling. I believe this is because the higher the level of testing the fewer public interfaces are thought about at lower levels. As for percentages about speed and coverage, that seems like a bad trade off of…
That is a terrible recommendation. Unless writing less code comes at the expense of readability or coupling you should always aim to write less code instead of more.
>Unit tests actually tend to favor highly uncoupled code while integration seem to favor more coupling with e2e favoring the most coupling.
It's the exact opposite. End to end tests do not even necessarily couple to a language, let alone specific modules. They can be used to refactor virtually the entire code base without rewriting any test code.
That isn't to say that you should only use E2E tests. IMHO wherever there is a naturally loose coupling and a clean, relatively unchanging interface - that is a good place to cover with integration tests.
The worst thing to surround with tests is a module whose API you know you will be changing (which will break the test when you do).
>As for percentages about speed and coverage, that seems like a bad trade off of 5% gain for 100% slow down. Especially because test time compounds.
No, it's an excellent trade off. CPU time is dirt cheap and bugs are very expensive.
Moreover, you can run regression test suites while you eat, sleep and visit the water cooler so the absolute time does not really matter provided it catches bugs before release.
Re: Write tests. Not too many. Mostly integration
#113Earlier quoted context omitted.
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 be…
Define "all written". If we are talking about a new function - obviously you write you comment for it after the function ready to be commented on. And obviously you won't be commenting every string you put there, right?
Now, if we are talking about the whole new feature, that can consist of many functions and whatever - yeah, you usually comment your code in the process of writting the feature, rather than doing it at a later time, which will never come.
Re: Write tests. Not too many. Mostly integration
#114Re: Write tests. Not too many. Mostly integration
#115Earlier quoted context omitted.
>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
#116Earlier quoted context omitted.
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 be…
> 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. Not to take the analogy too far, but usually when writing a chunk of code I can keep it's b…
Re: Write tests. Not too many. Mostly integration
#117Earlier 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…
There is some cargo culting there but it's mostly correct. Helper is a code smell as it's a sign of "we don't know what the responsibility of this is or what to call it so we'll just chuck a load of shit in this file and call it a helper" . The methods in should belong to something and live on that class, not in an external class. RequestExtensions is more shit than the original solution. Extension methods are even w…
For example would you argue against string formatting helpers? Or would they need to be written to an interface and added to myriad DI bucket lists?
Re: Write tests. Not too many. Mostly integration
#118Good 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…
> 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…
Wow, this is exactely totally opposite of how one can achieve testability in OOP! For more details I recommend excellent Misko Hevery's article "Static Methods are Death to Testability" [1]. Also, I'd argue that "functional style in OOP" is an oxymoron - you're either OO or something else (functional, imperative...)
[1] http://misko.hevery.com/2008/12/15/static-methods-are-death-...
Re: Write tests. Not too many. Mostly integration
#119Earlier quoted context omitted.
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 wi…