TDD is great when you have a very narrow use case, for example an algorithm. Where you already know beforehand: If I throw A in B should come out. If I throw B in C should come out. If I throw Z in an error should be thrown. And so on.
For that it’s awesome, which is mostly algorithms.
In real CRUD apps though? You have to write the actual implementation before the tests. Because in the tests you have to mock all the dependencies you used. Come up with fake test data. Mock functions from other classes you aren’t currently testing and so on. You could try TDD for this, but then you probably spend ten times longer writing and re-writing tests :-/
After a while it boils down to: Small unit tests where they make sense. Then system wide integration tests for complex use-cases.
then you probably spend ten times longer writing and re-writing tests
This is always what I’ve seen personally when people use TDD. And it’s worse because the inevitable time crunch towards the end of the project means the developers stop maintaining the tests, which renders all of the work put into the tests up to that point useless.
That’s not a problem with unit tests, that’s a problem with project management
Well put.
Totally agree.
I think we should all strive to do better. Unit tests, mock-ups, UX design, 2 week sprints with actual working deliverables, well documented use cases, every thing neatly stacked in Jira, dev,test,staging,prod environments, continuous integration and every thing else we are told to do.
Then reality sets in……
With all that said, 25 years as a dev, this utopian environment is almost impossible to find unless forced by regulatory compliance. Medical devices, life critical systems, etc. or if you have big piles of money.
In my experience, those things tend to be forced by project managers who believe the highest law of the land is proper scrum. Unsurprisingly, this makes all the devs miserable with no way to change anything because “this is just how it’s done”.
It’s also great for bug fixes. Write that sucker first and you have an easy way to reproduce the issue and check whether it’s fixed.
Yeah, I’m constantly recommending junior devs to use TDD specifically for this. I don’t recommend it for anything else. If they don’t write the test first, it’s possible that the test will end up testing the wrong thing and thus they can’t be sure they really did fix the bug.
Sometimes it’s hard to tell where to write the test ahead of time, so sometimes a slight variation I do is to write the test after (usually because it was such a struggle to figure out where the bug is), but when I’m testing it, I’ll comment out the fix or whatever and make sure the test fails.
I mean, it sounds more like “The messier your project, the more difficult the unit testing”. What you’re describing sounds like issues with SRP and LoD. Which will inevitably happen as big projects get rushed, but let’s place the blame where it belongs: rushing.
Yes unit tests take longer up front, but for projects that you need to update and maintain for a long time, they’re a huge boon.
You can’t do everything with a unit test obviously.
Works great when you know what your doing before you start. That never actually happens in real life though.
And often if you box yourself into an API before you start implementing, it comes out worse.
I always learn a lot about the problem space once I start coding, and use that knowledge to refine the API of my system as I work.
With my stakeholders TDD is nearly impossible. I mean it’s possible, but doesn’t make sense as they shuffle their specifications every other day. I implement, they decide they wanted something different, I refactor, they don’t like it, I refactor, they accept, I write tests.
Please send help
Send help? We’re all caught in the same fire.
I found a solution: I quit coding and became a school bus driver.
deleted by creator
I feel you, man. 🍻
It’s criminally underutilized. Of course, one reason is that it’s hard to TDD a moving target. Since it’s also hard to get people to actually fucking specify things in a lot of real world cases, it’s just one more thing you ought to do, but aren’t allowed to.
I think you have a point with the moving target, but also I believe that development should pretty much always be a moving target. You should be refactoring your domain based on new experiences and new knowledge all the time. So, personally, I find integration tests much more useful, because they test the input and output of a system, rather than how it’s implemented. I can change my domain without having to modify my tests and that makes changes to the domain much simpler.
That being said, I also definitely recognize the advantages of TDD, I just don’t think it’s a silver bullet; there’s good projects for it and bad ones
I write my code, comment it out, write tests that fail, then uncomment my code, then do the proper TDD loop. Some folks get too strict about the process at the beginning saying that that a test that doesn’t compile is still a failing test. My brain doesn’t work like that.
Sounds like you either need to establish better task parameters or you need to gain more experience programming.
This is very true.
Unfortunately most product managers SUCK at designing or making software.
Agile tries to fix this be supporting frequent iteration.
Unfortunately most programmers SUCK at writing good code.
TDD tries to fix this by forcing the consideration of end results (testing) at the beginning. It forces programmers and product teams to actually think and work. Make clear design decisions earlier on, but not to the point of waterfall.
It’s just a giant cesspool of failure due to human laziness that usually falls on the shoulders of QA.
Bottom line, making good software is hard. It takes time. But the market won’t support slow development. The business and sales teams remind me of Veruca Salt in Willy Wonka.
expired
How would you know what you’re going to need or what it can do before you code it ?
Well so before you code it you still have an idea of what you want the program to do, right? So you write a test for the program to pass or fail based on that idea of functionality, and then you write the program to pass the test.
So for something simple like programming a calculator you might write test code that verifies whether your addition function properly adds two numbers together then write the actual addition function.
Later on as you continue to build the program your addition test will still be out there verifying that you haven’t broken anything with subsequent code.
Some people will tell you that TDD tends to work better with established codebases in corporate environments where you have huge interrelated programs and maybe hundreds or even thousands of developers working concurrently as opposed to simple projects or startups where you might want to prioritize having a product set out before you start to implement rigorous testing requirements.
A lot of people don’t like TDD because they see it as extra overhead and don’t want to spend time writing test code when they could be writing “real code.”
Proponents of TDD tend to point to the fact that it contributes to stability in the overall codebase and allows you to quickly and easily find and diagnose problems, and it can make you a better developer to think ahead rather than just dumping code into the codebase and assuming it’s going to work.
Yeah, TDD is all fine and stuff until you have a system that communicates to a lot of other systems, and also has some weird dependencies, and since you are unit testing you need 300 foxtures and 100 mocks just to get the required coverage and then COVERAGE IS A FUCKING LIE.
The Test part of TDD isn’t meant to encompass your whole need before developing the application. It’s function-by function based. It also forces you to not have giant functions. Let’s say you’re making a compiler. First you need to parse text. Idk what language structure we are doing yet but first we need to tokenize our steam. You write a test that inputs
hello world
into your tokenizer then expects two tokens back. You start implementing your tokenizer. Repeat for parser. Then you realize you need to tokenize numbers too. So you go back and make a token test for numbers.So you don’t need to make all the tests ahead of time. You just expand at the smallest test possible.
It also forces you to not have giant functions.
No, being unable to read giant functions is what forces me not to have giant functions.
My friend, let me tell you a story during my studies when I had to help someone find a bug in their 1383-line long main() in C… on the other hand I think Ill spare you from the gruesome details, but it took me 30 hours.
Case in point, actually. Whenever I’m forced to write a giant function, I always get nervous because it could be crawling with bugs that I have little hope of spotting.
I don’t know if you’re joking or not. I suppose tdd will help know what you need before you start.
It doesn’t even sound great in theory. It sounds backwards in theory.
TDD is actually helpful once you get the hang of it.
It is a lifesaver in some cases
Elaborate.
I do it sometimes, especially when the bug is hard to reproduce and I know exactly what’s causing it. Sometimes it’s quicker to write the tests than to test manually.
Years of experience speaking:
- Make it work
- Make it right
- Make it fast
If your end results are following this pattern, no one gives a fuck how you do
Make it maintainable should be up there too.
I’ve worked with projects that does the right thing, but no one can add new features to it because it’s a nightmare to work with. It’s at the level of not being able to move a button on the UI without breaking how the software interacts with the cloud.
Pick two.
Nah, do all three. That should have been a numbered list.
I actually love using TDD in my real life development job…
TDD is up there with CBT if no one knows how to implement it properly
Cock and Ball torture simply must be done right