9 ms·
Like any TDD proponent (and most cultists, really), the author insists that „you're not doing it right”, despite reading the scriptures. You're always misunders
by dorinlazar 5y ago
Like any TDD proponent (and most cultists, really), the author insists that „you're not doing it right”, despite reading the scriptures. You're always misunderstanding, YOU are the reason TDD doesn't work, no, TDD is itself flawless. There's always a slight misinterpretation of the magic words! But TDD works, you're the sinner for not using it right!
And then you have shocked people when they find out that 100% test coverage doesn't mean that you really have a bug-free codebase.
- HelloNurse 5y agoThere's a hierarchy of smartness: good enough to write perfect code and need no tests, good enough to catch problems with tests, good enough to believe that better techniques would have allowed catching bugs that slipped through tests. Any technique, in retrospect, could have been applied better, in an improved form.
- ribs 5y agoThe author has described what they thing would make the practice of TDD better. The rationale presented isn’t ridiculous. Reasonable people could disagree on it.
- WolfOliver 5y agoNo body is saying it does not work per se. But how many test suite have you seen which are less helpful?
- pech0rin 5y agoQuite a few people are saying it doesn’t work. I have worked on TDD codebases where anytime you changed a function or tried to refactor something trivial it took 3x the amount of time to fix the tests even though the code worked correctly as written. This is due to mocking or naming or expecting functions to never change. TDD proponents would say that is the “wrong” way to do it, which Im sure it is but that doesn’t stop it from happening and killing productivity.
- the_gipsy 5y ago3x is optimistic. Tests can "suffocate" a codebase to the point where no one dares to make any cross-cutting changes anymore, at all.
- convolvatron 5y agoparticularly since TDD organizations often maintain the constraint that the tests _should never change_ since they somehow embody the requirements. personally I'm not settled on an architecture until I'm part of the way through..I can't really understand how its all going to fit together until I'm in the process of building it.
- WolfOliver 5y agoThis matches with what the articles says: > "You change a little thing in your code and the only thing the tests suite tells you is that you will be busy the rest of the day fixing false positives."
- pydry 5y agoI have encountered this too, just as you and the author did. However, when I switched to integration testing behaviors rather than unit testing low level functions as the author suggests it went away. Traditional TDD proponents would say that what we're doing is definitely not orthodox TDD but IMHO it's the only way that actually works.
- usrusr 5y ago...and the 3x amount of time isn't even the biggest downside when that happens, that honor goes to how much the value of those tests erodes while they are being adopted.
- falcolas 5y ago> But how many test suite have you seen which are less helpful? I got ya. I have worked on software with a buggered mix of mocked and integration tests that fails about one time in four. But since the bug was in some asynchronous code and would appear in random tests, with random errors (even on thoroughly mocked tests), we can't easily smash it. It's one of those heisenbugs where enabling logging would cause all the tests to pass consistently. And to put icing this cake, the software worked - this bug wouldn't appear in the production deploy. So, yeah. The test suite was less than helpful. It certainly couldn't prove any qualities about the software we were writing.
- eb0la 5y ago> you have shocked people when they find out that 100% test coverage doesn't mean that you really have a bug-free codebase. This applies specially to business people. 100% test coverage just means you tested that s*t with all you expected... ...but your software does not live isolated. Some external system may have a bug, or may inject some unforeseen values, or a solar flare might flip the value of a bit in your system and crash your software.
- yakubin 5y agoI see completely different problem. Just because there are branches in your code, doesn't mean there are branches in its inputs. And just because there are branches in the inputs, doesn't mean they are reflected in the code. So you may have 100% test coverage, but be testing branches which aren't going to be taken, at the same time completely missing the branches that are in the inputs, which you'll fail to handle. Example: fn abs(x: i32) -> u32 { x as u32 } fn test_abs() { assert_eq!(5, abs(5)); } Boom, 100% test coverage! But the tests are actually very low quality. There is a bug when x is negative. That's why property-based testing is nice. It uncovers branches in the inputs (although the task of generating a representative set for the inputs is sometimes non-trivial). After discovering the bug, one may even write a branchless implementation of this function for performance without updating the test, and it will still be 100% coverage. But the arithmetic has "logical branches" which do not look like ifs, instead they generate qualitatively different results for different inputs.
- pydry 5y agoI tend to find logical/algorithmic bugs overemphasized. Property tests are nice and work very well for extremely complex algorithmic code that has simple inputs and outputs but most code I write at work simply isnt that. In school I wrote parsers. At work I have done it but it's rare. In fact if you write commercial code you'll often find that the code that you rely on that is like that weirdly gets concentrated in open source libraries which you will be testing only indirectly. Certainly when writing commercial code I find that the majority of bugs lurk in the interstitial spaces between subsystems I am integrating or in misunderstandings about how the overall system or subparts of it are supposed to behave. And property tests are not much help there and unit tests are often a hindrance (because theyre as likely to bake in wrong assumptions). TDD is some help with this but only if A) it's paired with BDD to exorcize specification bugs and B) done with integration tests that exercise all parts of the system together.
- rmetzler 5y agoBut being 100% bug free is not the goal of TDD?
- belter 5y agoWe are in the year 2022. We don't have the technology to produce bug free software based solutions. 100% code coverage, as other mentioned in this thread, does not guarantee you exercised 100% of all the inputs values possible. That is why: - You can pay millions of dollars to a Software Company, and when you install the product the usual license text, says something in capitals along the lines of: NO GUARANTEES WHATSOEVER FOR ANYTHING... plus some will mention you can't use for controlling X-Ray machines, Nuclear Power generators and so. and also why - Software where life depends on, normally will use a type of summation or consensus based software like the Shuttle had with 3/4 computers.
- marginalia_nu 5y agoI don't think it's entirely technological limitation. More often than not, the discovery of bugs is increased understanding of what we require from the code. We often say a code is buggy when it surprises us in some fashion, then we tacitly invent a new requirement we say it has violated. If you have a function F(signed int32 n) -> (signed int32 A, signed int32 B) that returns two integers (A, B) so that A*B = n and we discover that F(2) -> (-2, 2147483647), which is entirely correct in a language that permits integer overflow; then we call it a bug because A and B must be smaller than n (or whatever). This was not a requirement until the bug was discovered.
- rmetzler 5y agoI’m not really sure if this was understandable, but I’m basically in the same camp as you are. It’s next to impossible to have 100% bug free code. Automatic testing helps and TDD helps to write tests, but it’s not the goal. The goal is to create code that is well tested and easy to change.
- jnash 5y ago> We don't have the technology to produce bug free software based solutions. Not correct. See seL4, CompCert etc.
- manuelabeledo 5y ago> But TDD works, you're the sinner for not using it right! I often tell my colleagues that if technologies or methodologies are widely misunderstood, then practitioners aren’t to blame. TDD might be great, but I have yet to see it widely succeed because its adoption is troublesome. It’s a bit like any of these newest products that promise to address everything consumers demand, only to fail miserably against the same old, leaving the few adopters asking themselves why commoners didn’t get it.
- gpderetta 5y agoI believe that in medicine, if a treatment fail because the patient doesn't follow it correctly, it is considered a failure of the treatment (of course better education can be part of the solution).
- pydry 5y agoThere are a number of tech fads that were unknowingly widely promoted as a panacea whose applicability is limited to particular specific circumstances. Microservices is another. TDD gets pushed especially hard (I think) because when it works well it works REALLY well and because it can be quite literally addictive - the red/green being like sounds on a slot machine that generate a hit of dopamine. Thats a recipe for some passionate promotion. In fairness to the original author, his heterodox form of TDD does widen its applicability beyond its traditional scope of complex, stateless algorithmic code with simple APIs to the more common integration code that involves databases, etc. that predominates in most commercial code bases.
- parasubvert 5y agoBut, what tech innovation DIDN’T start as something with limited applicability? The only way to know is to discuss the benefits and tradeoffs in something approaching social science. But humans struggle with rigor, it’s much easier to brand and market something, or to buy in to brands. So “ideas” like microservices become brands. And they’re misunderstood and misapplied because people don’t read the copious literature that discusses the tradeoffs and variations. And they don’t practice it as a discipline with someone that has mastered the technique successfully: they do it blind. Same goes for TDD or other XP practices that are often deride as cultish. being a discipline is even harder to adopt than a design philosophy like microservices. Disciplines are about consistent behaviour. To an outsider, it’s freaky. But calling it cultish as some do is like saying Karate or another martial art is a cult. From the outside it kind of looks like it, but discipline or kata (practice of form) is known to be a success multiplier for the sustained successful application of practices. If you don’t have a dojo or a sensei, could you teach yourself such a set of martial arts to mastery? If not, why do we expect everyone to pick up TDD after reading a book?
- pif 5y ago[flagged]
- hk1337 5y agoI think people try too hard to make it work and end up trying to apply these strict adherences. Same thing with agile and pair programming.
- Existenceblinks 5y agoMy best testing practice is writing tests as needed based on instinct. YES. I can feel it when a function needs test or not. It will hint by giving a little anxiety on expected result of that function. And I don't care 100% coverage anymore.
- TravHatesMe 5y agoBut this approach doesn't scale. How can you expect everyone to have this intuition? Agreed that 100% coverage is stupid.
- Existenceblinks 5y agoSo currently there is no any approach that scale at all. Everyone will write test differently. And that's why we have code review process, and senior software engineers? --- EDIT: add an example When you look at a body of function and think if someone else changes some codes and you will have a hard time figuring out what goes wrong, that, the time you need to add some tests to it. Often it's a function that took numbers of iteration to work as you expect, or a function that is not simple but look so easy you write it right in one go.
- devoutsalsa 5y agoI’ve never seen an approach that scales. Once a team passes a certain size, it all turns into a disorganized shit show. Communication is hard, and as the pressure to earn revenue intensifies, there’s less & less time or buy in for craftsmanship.
- Existenceblinks 5y agoYep, true. I'm really familiar with the vibe of time-to-market vs not to fuck customers up. Modules that are directly related to values to customers get more tests.
- notepalf 5y agoWhy is 100% coverage stupid? I agree that there could be configuration or data classes that does not make sense to test, so these could be ignored by the coverage tool. Is it still stupid to aim for 100% coverage in the rest of the relevant not-ignored code?
- ragnese 5y agoAnd on the flip side: what if they're right and you are just doing it wrong? I understand the point you're making. But, I find this retort to be every bit as frustrating as the rhetoric you're criticizing. It gives us permission to dismiss things we don't fully understand or that require experience and practice to master as snake oil. Surely most of us would struggle to pick up general relativity or neurosurgery even after weeks or months of training. But we're not--I hope--going to dismiss our neurosurgeon instructor when they say we were cutting something incorrectly even though we REALLY THOUGHT we were doing it right this time. Maybe TDD really is awesome. And maybe, simultaneously, it's not easy to write a 100% prescriptive guide for how to apply it to every kind of project. I feel similarly about the rhetoric around OOP. Nine times out of ten, someone complains about OOP and cites some kind of Poodle-Dog-Animal class hierarchy. Then someone comes and says that program object relationships aren't really supposed to be taxonomical. Instead of taking that to heart and wondering if maybe they can try OOP again with a different mindset, the response is defensive. "Surely OOP is still terrible because I was taught the wrong way. And if it's possible to employ a technique ineffectively, then it must be a terrible technique. OOP sucks and they're in a cult so they can't admit it." Do you have any idea how many wrong ways there are to use the controls in an automobile? Yet we still mostly blame the drivers when they cause a collision because they were using it wrong. For what it's worth, I think the article is right about the evolution of the term "unit test" and the author mentions the "classicist" approach to unit testing, which is really the one that makes sense with TDD. The "mockist" approach to unit testing, is "simpler" because it just makes an individual class or function the "unit", but that will make tests brittle and make a test-driven approach much more verbose and cumbersome. It also so happens that the mockist approach is the default approach in today's programming languages, testing-frameworks, IDEs, etc.
- taeric 5y agoI don't know, your examples feel a bit off. Surgery spends a ton of time on the techniques of surgery, sure. And yet we still had a proliferation of excess back surgery that was, in retrospect, unnecessary and we have taken effort to stop that. Similarly for driving, you are right that media often blames the drivers; but civil engineering looks at the roads that have more wrecks than others and looks to see why that is. TDD suffers because it is a tool. As soon as it exists for its own sake, expect that it will be over used. This is more complicated because Tests are themselves a tool. So, having a tool that exists only for the sake of another tool, and it is not too far to see how this one is less clear cut.
- hinkley 5y agoThis is an area where suitable extracurricular activities can give more perspective on things. In many disciplines there are activities that end up feeling like 'scaffolding', learning exercises that you don't necessarily do all the time. They make you a better practitioner the first time you do them, continue to add value for some time, and then are useful from time to time as a refresher. I think if you've never done TDD, you're missing out. If you had to be dragged kicking and screaming into it, you're missing out (possibly have damaged yourself in the process) You don't need to make a cult out of it (and I suspect some of the resistance to it is from people who feel like they're being asked to join one), anymore than you have to religiously clean your shoes to see value from having a set of cleaning tools. The same for pair programming. It makes you look at some classes of problem in an new way, and those lessons can stick with you even when you are working alone on a personal project. Most of the time these days I tend to do a testing sandwich. When I'm still trying to figure out what the APIs will allow I'm free-form writing code trying to stick the concepts together. At some point I get stuck trying to juggle corner cases, and I realize that I'm grinding gears and need to write test code for a while. At this point I still get a lot of the ergonomics benefits of TDD because I'm not yet wedded to my implementation (low sunk cost) - because it doesn't work anyway.
- coward123 5y agoOutside Smalltalk, TDD has never "worked" for me. But in a Smalltalk environment it was an absolute no-brainer and super slick because the environment was set up for it to just work. The nuance is the code-build-test cycle. In Smalltalk, they were all one and the same. In other languages and with other VMs, that cycle is disconnected. Likewise, once we moved to web applications, things changed. Now the unit we want to test is the API, or the widget, not really the function per se, but every TDD tradition has been at a much lower level. It overlooks that it takes real time and energy to build out tests at that higher level, and there are better tools than what have traditionally been "TDD."