11 ms·
Experts, True Believers and Test-Driven Development: how advice becomes a religion
- juskrey 10y agoI'm 17 years into coding and have never even tried TDD - just because it seemed horribly wrong.
- marsrover 10y agoAnd this is the other end of the spectrum, which is equally as bad. Don't be the guy who never tries new things.
- juskrey 10y agoMost of my new things fail even before I write a first test for them.
- Mikushi 10y agoIs it equally bad? I didn't do TDD most of my career, product I delivered worked, where delivered on time and reached the goals set out by the business. Why bother? Because it's good practice? Hardly a valid argument in a business perspective.
- rorykoehler 10y agoI use it because it's faster and it makes making changes later easier. It also allows me to leave the app mid-feature (happens a lot as I do more than just code) and comes back to it without having to load the whole app into my mind again. If I get my specs to pass then the app will work. Simple.
- zachrose 10y ago"Business perspective" can be like hill climbing: you evaluate a potential direction based on whether it makes your situation more profitable or less profitable, regardless of the peculiarities of your local landscape. I think got into TDD for its aesthetic or philosophical appeal. The idea of being able to make reliable software by first writing down what its supposed to do just struck me a poetic and tractable. On the one hand, I spent a lot of time and money going through a dip in productivity while learning all the things to make testing work for me. On the other hand, I eventually emerged from that dip with skills and a mentality that allow me to be productive and relaxed in a way that I wouldn't have thought was possible.
- RyanZAG 10y agoRemember the mind map craze? For a few years, educators everywhere wanted you to do almost all learning by drawing circles with words and connecting them. For many people, this type of visual link between concepts allows them to learn far faster than regular textbook style. For some people, mind maps make zero sense and they learn far slower. Some concepts just don't fit into mind maps at all and even for very visual people it just slows them down. There's often a more specific visual learning method for many problems than a simple mind map too. TDD is mind maps. Give it a try, but don't feel bad just because mind maps don't gel with your brain.
- Jtsummers 10y agoI'm unfamiliar with the mind map craze. I'm familiar with them, we used the concept as a tool in grade school for writing essays and papers. I'm curious where and when it became dogmatic for some educators to push it beyond "this is a tool that can be useful, use it for some tasks and see how it works" to "this tool is the shit, mind map all the things".
- douche 10y agoEducation is almost as cargo-culty as software development, with nearly as little empirical research being done to check the validity of the various schools of pseudo-religious dogma.
- neurotrace 10y agoI wouldn't call myself a regular practitioner of TDD but I can tell you that it's incredibly valuable in certain circumstances. When you're writing code that, for example, must be mathematically accurate, writing unit tests can be very useful just so you can assure yourself that you wrote the calculations down correctly. They're also very useful for other "pure" operations. A factory should always produce an object with such and such properties. A user input validation method should always fail given some classification of invalid input, etc. Hardcore TDD is definitely not The Way for me but it's very good to use at times. You'd be amazed how much it speeds up testing these kinds of processes when you can just watch your list of tests change from pass to fail or vice versa. As with anything, your mileage may vary.
- RyanZAG 10y agoI think you're confusing TDD with unit testing. You can unit test without TDD.
- neurotrace 10y agoI'm not. I know you can do TDD without unit testing but it's very rare in my experience. I'm saying that the TDD cycle (write tests, run all and verify failures, write actual code, run all tests hoping to see no failures, refactor as needed until step 4 passes) works best when applied to unit tests. Integration tests, acceptance tests, and other "big" tests don't lend themselves well to that style of programming, in my opinion.
- ldjb 10y agoI think RyanZAG is saying you can do unit testing outside of TDD, not that you can do TDD without unit testing. The fact is that both are true. You don't need TDD to use unit testing — you can implement first and test afterwards. In some cases, this may actually be preferable. However, although TDD isn't a silver bullet solution, it can be very helpful in a lot of cases. Like with a lot of things, the usefulness of TDD depends on the situation at hand, and a good software engineer chooses the right development techniques for the job. Unit testing of some sort, however, is considered good practice regardless of whether you're using TDD or not. (And of course, integration and acceptance testing is a good idea, too.)
- jon-wood 10y agoWhat about it seem so horribly wrong to you? I'm by no means a zealot, and will often build things before writing tests, but there are definitely some problem spaces such as writing reusable libraries where going the other way round is a big help.
- juskrey 10y agoI can answer - most of the time I do not know at start what data structure/effect should be the exact result of my code, even if it is just a more complicated version of the "hello world".
- heimidal 10y agoIn TDD, you write the test to help figure this out. The idea is that you start with "how do I call this method/interact with this code/etc?", then ask yourself, "what should the result be?" TDD is meant to help inform your design thinking, but there's no rule that says you can't change your mind as you go.
- AnimalMuppet 10y agoIn particular, you should be changing your mind as a result of trying to write the tests. If it's hard to write a test, that's telling you something - the interface is clumsy to use, for example. TDD is different from just writing tests, because the tests drive development. "Drive" may be a bit too strong, but they at least significantly influence it.
- ajmurmann 10y agoIn that case write higher level tests. TDD works best and provides most value when you go outside in. So your initial test would just determine that you expect to see "hello world" printed. Maybe on the next level down you now have to do some validation and you have to define how the interface (not used in the Java sense here) of the function or object or whatever looks that does the validation. The key thing here is that you don't need to think about how that will actually work on the inside, but how you want it to be exposed. As you start to TDD that portion of your code that implements that new functionality your tests shouldn't care too much about how the code under test is implemented, only about its outside behavior (this might include calls to other functions though that ideally get mocked). This process makes it easier to many practitioners to increment on functionality that they don't know in advance how to implement. That's why it's called "test driven development" and not"test first development". All that being said, determining the right amount and granularity of tests is certainly much more of an art than a science and friends on the developer(s), what the system is doing, framework and the language you are using. I definitely write many more tests when I'm writing Ruby code than when I'm writing Rust. I'm also very new to Rust so we will see if that lasts.
- pmarreck 10y agoThe only thing that has made me even more productive than TDD is functional programming/immutability (in conjunction with TDD). You're basically wasting your time not doing it. If you want maximal productivity, learn TDD. Writing unit tests upfront is most definitely a case of "one step backward, two steps forward." Your code under test will be written better (which is to say, more modular/less cyclomatically-complex/easier to maintain and refactor), you'll break it far less often (from the same body of code or other code that relies on it), and you'll feel far more confident about your code. You won't be afraid to refactor it (afraid that you'll break something) because the tests validate it. It's also invaluable on teams, where not everyone is sharing the same mental model. Speaking of which, remember that your mental model of the code is the true limitation. Unit tests allow you to offload some of that, so that you no longer have to have a perfect representation of all possible states your code can produce, inside your head (which if even possible would allow you to write perfect bug-free code). This is incredibly liberating. You can literally feel the difference. I know it sounds all touchy-feely to describe it this way, but so be it. But hey... If you can imagine every possible state all your code will ever produce at all times, you don't need TDD nor unit-testing, because you already know the "fails". ;)
- Spooky23 10y agoAll methodology has the potential to become pseudo-religion. The worst ones are the ones that infect every aspect of the business like ITIL. The scope and complexity of the methodology is so broad, you need to hire priests (ie. consultants) and build shrines (ServiceNow, Remedy, etc) to the religion and you end up in a state where nobody in the business understands WTF is going on. That answers the question frequently asked here re: why horrific and dysfunctional companies like IBM get a tight grip on companies.
- lgleason 10y agoSix sigma is definitely that way, especially when you consider that, like AA, it is a 12 step program. On a side note if you put the two lists next to each other six sigma almost looks like a dispassionate generalized version of AA ...
- maxxxxx 10y agoYou can replace TDD with object orientation, functional programming, scrum and other buzzwords. I never understood why people try to make everything into a rigid religion. Maybe it's a substitute for thinking for themselves?
- sageikosa 10y agoIf we build the coconut airports, the planes and cargo will come.
- oddlyaromatic 10y agoDecisions are costly, and things that reduce the number of decisions you have to make can be useful in moving work forward and making you more productive. Out at least making you feel productive. It's obviously not a great idea to follow one paradigm always, whether it's appropriate or not. But I think it's attractive for the reason you mention. We can't reason about every little thing all day long, so rubrics that come from trusted experts both reduce cognitive overhead and make us feel like we have "borrowed" somebody else's expertise.
- maxxxxx 10y agoI can see the benefits of reducing decision time. But I have seen it many times that you start with some paradigm which at the beginning is useful. But over time you discover more and more conditions where it doesn't work well anymore. Instead of reevaluating the situation a lot of people just stick to the paradigm although it's obviously not useful anymore. I see that a lot with scrum people where the answer is often "you are doing it wrong" but they are not able to answer the question how to do it right.
- mi100hael 10y agoOn the flip side, I find having a system like Scrum is beneficial even when parts of it are being done wrong because it's still an agreed-upon system that the entire team adheres to. Having 5 or 10 people each going at things the way they see best based on their experiential understanding can lead to counterproductive chaos even if each individual's approach in a vacuum is sound.
- Murk 10y agoIt happens all the time. It happened with "design patterns". It happens with frameworks, languages, and many other things. Human nature. It's quite hard to argue with someone who cites an "expert", because you are a relative nobody. Always think for yourself.
- protonfish 10y agoBut where does "thinking for yourself" become "reinventing the wheel"?
- falcolas 10y agoIt happens remarkably easily. But like every other mistake, this is one you frequently have to make for yourself to understand why it's a mistake. The trick is having enough introspective capability to identify when you have made a mistake, and not fall back on dogma to say "I followed The Path, so it can't be a mistake".
- NikolaeVarius 10y agoNot specific to Code. See Also Health Advice Including but not limited to (Diets, GMO, Types of Exersize/Timings) People want something to latch onto and feel superior about.
- enraged_camel 10y agoI think the difference with healthcare advice, at least with the examples you gave, is that the effects are directly measurable. If I am eating 2000 calories a day now, and start eating 2500 calories a day, I can measure the impact of that change on my weight as well as my lifting performance. I really doubt the impact of TDD is directly measurable like this. I may be wrong though.
- BeetleB 10y ago>I think the difference with healthcare advice, at least with the examples you gave, is that the effects are directly measurable. Nope. "Oh, you have this problem? You probably don't take enough Vitamin D!" "Oh, you have this problem? It's probably due to lack of exercise." "Oh, you have this problem? You're probably not drinking enough water."
- AnimalMuppet 10y agoMeasure it by the bug count over a release cycle.
- curun1r 10y agoThis is so not new, it has been covered in religions for thousands of years. Buddhist teachings tell that there are three forms of understanding. The first is devotional understanding. Martin Fowler is a wise and learned programmer and says that TDD is the best way, so One believes that. The second is intellectual understanding. TDD is good because it codifies the programmer's intentions for what the code should do, makes refactoring easier, prevents regressions and all the other logical reasons that TDD proponents talk about. The third kind, and the only one that's true understanding, is experiential understanding. TDD is good because you've experienced development with and without it and feel how different they are. Once you get to this point, there's no dogma about writing tests first or anything of that nature. The practice becomes natural and you're free to deviate when it feels wrong. See also: Shu Ha Ri
- itamarst 10y agoThe interesting thing about this model is that it maps pretty directly to current research on learning. In this context, experiential understanding (when you're an expert) is the point where you start suffering from Expert Blind Spot. And there's a bunch of research that suggests the best teachers (by default) are the people at middle point, intellectual understanding, precisely because the understanding is less automatic and integrated. The book "How Learning Works" (which I review at https://codewithoutrules.com/2016/03/19/how-learning-works/ https://codewithoutrules.com/2016/03/19/how-learning-works/) talks about this at length.
- steveklabnik 10y agoOr, arguably, the interesting thing about current research on learning is that it maps pretty directly to things Buddhists have been saying for thousands of years. (I know nothing about Buddhism or learning research, just making a point about chronology.)
- wpietri 10y agoInteresting. For me, teaching when I'm an expert means I must begin another path of learning. I'm at Ri in understanding the material, but at Shu at understanding how novices see the material. But I could well believe people at the middle point will always be better than me. For those who want a good example, I strongly recommend Julia Evans, aka @b04k: http://jvns.ca/ http://jvns.ca/ She writes a lot of novice-focused material on technology. She does a much better job at explaining things than I would. And she does it with an excitement for the material that is infectious. Even for those who know the technical details, I recommend following her; I always walk away saying, "Wow, she's right! I had forgotten how cool that is!"
- Silhouette 10y agoSadly, I don't think all of the black and white advocacy for certain ideas that we see from some sources in our industry is because the experts don't realise how expert they are. I think much of it is because it sells more books and consulting gigs, and because being controversial helps to keep a high profile.
- dep_b 10y agoI see a lot of projects where everything is just a vast context based decisions. If you factor out all of the things that are not related to databases or handling user input there's very little left. However I can imagine having that logic built up "abstractly" by imagining user input and database output objects and fully tested is something that would really help a project. Having only 20% code coverage or less is nothing to be ashamed of as long as that code is the code that matters and it's better, more abstract and more readable because you started writing it TDD. Before things got ugly with user input and database results.
- agentultra 10y ago> And if the director of a movie has asked you write some code to 3D render a "really awesome-looking explosion" you won't benefit much from unit tests either, unless you can write a unit test to determine awesomeness. I was skeptical of this post to begin with but this line sums it up for me. The author is railing against a perceived threat. Of course you can't unit test _awesome_. That's ridiculous. So what's the claim here? I think more developers need to be introduced to the concept of the, "state of the art," and be led to resources like SWEBOK[0]. It has a section on software testing and it's good to know what the state of the art is across the industry. I don't have the link in my db, but I've come across studies that have shown no significant difference in productivity when utilizing test-first vs. test-after approaches to software development. That's the only real religious sell I still hear these days and it has been rather well debunked at this point. All that matters is that software is tested... how you approach it seems to just be a matter personal preference. [0] https://www.computer.org/web/swebok/v3 https://www.computer.org/web/swebok/v3
- z3t4 10y agoI write the test before fixing the bug, so I can automatically repeat the bug, and make sure the test finds the bug.
- spdionis 10y agoAssuming you're fixing a bug...
- nickbauman 10y agoI find that systems written with few tests are inordinately hard to add tests to. So I tell people "please TDD" because if they don't, the tests are never backfilled.
- agentultra 10y agoThis is a common occurrence. The practice of writing tests shouldn't be avoided. You still have to write the unit tests which implies your code must also be testable. The difference in productivity between "write the test first," and "write the test after you've written a bit of code," don't seem to matter as much as "write the tests." As someone who reviews code for a good portion of my day it makes little difference to me how you, the programmer, managed to write the tests. We share the same goals and the end result seems to matter more than how it was accomplished.
- lgleason 10y agoIt's like design patterns, scrum etc.. When the tool is used correctly it is awesome. When it's mis-used it becomes a cargo cult style liability. With TDD a large part of the religion thing comes from people like Uncle Bob. It's not that his style is bad, but the biggest problem I've seen with his style is when people who are already passionate with their craft and maybe practicing TDD go crazy with his advice while missing the context of his message. That context is his focus towards systematically sloppy corporate shops that have picked up really bad habits and won't touch the tool.....often the same ones that still use a waterfall development process (now with a thin scrum veneer). When you have these kinds of shops it is probably better to to a bit to the other extreme first, and to then find a happy medium after you develop better habits and understand the tool .
- BeetleB 10y ago>With TDD a large part of the religion thing comes from people like Uncle Bob. It's not that his style is bad, but the biggest problem I've seen with his style is when people who are already passionate with their craft and maybe practicing TDD go crazy with his advice while missing the context of his message. I honestly don't know what Bob should do. I know he occasionally says stuff that gets people upset. However, the majority of the stuff that is attributed to him is just outright false. It doesn't matter how many times he publicly corrects the record. Uncle Bob does not believe in unit testing every function. Uncle Bob does not believe in a 1:1 mapping of function with unit test (or even close). Uncle Bob is fine if a unit test spans/covers multiple functions. Uncle Bob is not against unit tests that touch the database or disk. The list goes on and on. I watched many of his Clean Coder videos, and was surprised to see how nuanced he is. He does not speak in absolutes. His blog posts are much less polished, and often get him into trouble. But even there I see a fair amount of nuance.
- Silhouette 10y agoHe does not speak in absolutes. Not as often as some of his critics might suggest, perhaps, but he really does speak in absolutes at times and some of those absolutes really are as foolish as his critics say. He also frequently adopts a style that presents his personal opinions and experiences as if they were more than that, despite a lack of other evidence to support his positions or even the existence of other evidence that seems to undermine those positions. While he may hide a small disclaimer somewhere, many of his readers aren't going to see it, and I don't believe for a moment that he isn't fully aware of that when he chooses to present his material as he does.
- williamstein 10y agoMy experience: TDD is awesome for writing certain types of code... and it's terrible for writing other types of code. Simple as that. The same is true for many programming languages: good for somethings and terrible for others.
- pmarreck 10y agoWhat is it terrible for? I've encountered situations where someone believed it was bad for something and were wrong. Such as user interface code. The solution in that case for example is to make as much of the code testable as possible leaving just a thin layer of untestable stuff (which can still be tested via an integration test of some sort). This idea generally follows the principles of http://alistair.cockburn.us/Hexagonal+architecture http://alistair.cockburn.us/Hexagonal+architecture or "functional core, procedural IO". Gary Bernhardt expounds on this brilliantly in his https://www.destroyallsoftware.com/talks/boundaries https://www.destroyallsoftware.com/talks/boundaries talk, btw.
- wvenable 10y agoIt might also be good for certain types of programmers and worse for others. I tried to do TDD on an appropriate project but it hampered my creativity too much. I slowly started writing code ahead of the tests and ended up back to regular unit testing.
- deepaksurti 10y agoBy pg in On Lisp: >> It’s a long-standing principle of programming style that the functional elements of a program should not be too large. If some component of a program grows beyond the stage where it’s readily comprehensible, it becomes a mass of complexity which conceals errors as easily as a big city conceals fugitives. Such software will be hard to read, hard to test, and hard to debug. >>> One of the problem is not treating tests also as a design problem as in what to test and what the code for tests should be like? I never see the rule of simplicity applied to the test code as well. Eventually it all becomes like a big city that conceal fugitive bugs. EDIT: to end the quotation from pg book.
- kazinator 10y agoFugitives can hide very well in the backcountry too. And I'm not moving to a village. :)
- huherto 10y ago> You need to take every piece of advice and figure out when and where it does not apply. This. It is almost obvious. But you still see lots of cases where advice is followed where it doesn't make sense. A particular contrarian thing that I do in Java. When I need objects that are pure Data Transfer Objects (DTOs) with no logic whatsoever inside I just declare all members public and do not bother writing (or generating) getters and setters. I know we were told NEVER to do this. But in this case there is not attempt to encapsulate anything as there is nothing to encapsulate.
- douche 10y agoJava really needs to get auto-properties added in someday...
- data_hope 10y agoUh, I think every TDD "expert" makes it pretty clear, that there are cases where tests-first might not be the best option.
- clifanatic 10y agoI think a lot of this religious behavior stems from an underlying belief, mostly by people who've never tried it themselves, that programming _must be_ easy and anything that makes it appear hard (and especially slow) means that somebody is making a mistake somewhere. So they go looking for a silver bullet, and the latest fad seems to fit the bill.