5 ms·
This is not the best advice I've ever read, some of it smacks of "silver bullet" thinking. For example, it's sometimes better to duplicate than couple. Within t
by carl_sandland 7y ago
This is not the best advice I've ever read, some of it smacks of "silver bullet" thinking. For example, it's sometimes better to duplicate than couple. Within the same component sure don't copy pasta. Also I think TDD is frankly ridiculous; I've seen many teams spending more money on gold-plating test lines of code than actual code. I've seen other, better teams spend all their efforts on full integration testing only. There are no golden rules, it's just hard work.
- dogcomplex 7y agoYou're in good company with Jonathan Blow and, it appears, John Carmack. Teams pushing TDD might be a good smell test for whether they know how to efficiently code.
- carl_sandland 7y agoIf I was arrogant enough to consider myself a good programmer after 30 years of doing it, I would suggest as humbly as possible, that perhaps TDD is something better coders can do in their heads and 'skip over'. How do we know what API to build ? Because the code needs it. How we know the code works ? Because I just ran it.
- kbenson 7y agoWhich comes right back around to the idea of who you're writing code for. I suspect much, possibly most, of the time it's not purely for yourself, but for your team, or other Co tributes to the project, or thr person that has your job a few years from now, or even you a few years from now. Just because you have the entire system in your head right now, will you when you revisit it a year later to add a feature or fix a big? How much time will it take to internalize completely? Tests allow you to know less about the system overall and still make assured changes to smaller portions of it because prior you (or someone else) has spent the extra time to make sure any mistakes are caught early and easily. The go-to counter to this is that you should really know what you're doing and understand the system you're working in, but that's often not only infeasible, but impossible for one person (how well do you know all the libraries you're using?). There are plenty of codebase out there where I think no one person can internalize it all and understand it well enough to always make food choices, and since you'll have to choose what you want to remember, a helpful tool to make sure you don't violate some important facets of how it works is useful. Now, much of this is about testing in general, but if you think about it, there's a lot similar about writing new code and coming into a large chunk of code that you need to alter but you have limited understanding of or poor recollection of. The same things that keep you from violating how it should function help your design a coherent functionality in the first place.
- cjfd 7y agoUntil you mentioned him I had never heard of this Jonathan Blow character. The thing is both of these people seem to do game development. If you write code that is close to the hardware and needs every ounce of performance there might be a point to this. It would make applying TDD both harder to pull off and less beneficial. When one is writing complex logic that is supposed to receive both frequent new features and keep working correctly there is nothing that beats TDD. Let me attempt to compare this to bowling even though I know nothing about bowling. If you just occasionally like to go out bowling you can use whatever technique you like and you will get better if you just bowl a bit more often. If you want to play bowling on the national level you may at some point have to drop the technique that you made up yourself when you started out. You need to go through the uncomfortable stage of learning a new an better technique and temporarily be worse at it. I think the people not doing TDD are just refusing to go through this because there is not much of an objective standard of quality for developers. We are in a field where code that lacks any sort of quality is standard and where breaking features three times a week is standard. TDD will fix these things.
- 3fe9a03ccd14ca5 7y agoTDD works great when the requirements are known and there’s little mystery. Waterfall methods oddly enough lends themselves well for TDD, which is kind of associated with hip styles like agile. The reality is most projects start as exploration. What you’re thinking might not even be possible. Can you even approximate the classes you’ll need yet? For these scenarios TDD fits in awkwardly. I prefer to do a little back and forth. A little dev. When things are looking stable, a little resting. Towards the end a lot of testing.
- cjfd 7y agoThere is some point to your comment but also something that seem to me to be misunderstanding. Also, part of it seems self-contradictory to me. There can indeed be exploration stages where TDD does not help that much. E.g, if you are going to interface with a piece of hardware you have never seen before and you need to get some sort of working communication going there is much point to what you say. As soon as you know what sequence of commands makes the piece of hardware work one has arrived in the territory where TDD is highly beneficial. You can then write a test where you require that your software indeed produces the correct sequence of commands and after that you can refactor your exploratory code while having to check that it still works together with the hardware much less often then otherwise would be needed. The remark about TDD and waterfall seems much less true to me. In my original post I wrote 'both frequent new features and keep working correctly'. That does not describe waterfall at all. In fact, and this is where you messages seems to get a bit self-contradictory, your post actually sounds much more waterfally to me than mine. It contains the words 'Towards the end'. It is waterfall projects that have an end that was envisioned right from the start. Whatever 'agile' means, it seems to have the feature that we never stop adding features and that stuff is supposed to be in a working state in between adding these features. So, if one is actually doing that there are dragons in the sentence 'Towards the end a lot of testing' because it actually turns into 'always lots of testing' which costs lots of time. In case of the hardware example it would also require that every developer has a species of that hardware on his desk next to his computer. As I happen to work in a field where we interface with hardware that is three stories high, we should realize that this is not always practical. One misunderstanding that might be going on is that perhaps you are assuming that in TDD one would test just one class at a time. I generally prefer to test a set of classes, i.e., a subsystem of a whole program. In that case the test are about properties of the program that, in many cases, the user could recognize as beneficial. There should be less churn at that level. I suppose some people would call this behaviour driven development instead but I am not so very married to terminology and will just keep calling it TDD. Testing individual classes can also be helpful but if they contain rather simple logic I am not sure writing tests for that is so very helpful. At some point would just be testing whether the processor really is capable of copying values which is not that interesting.
- Aeolun 7y agoIf you already know how to code really well, you can easily make a test that tests the things you want to do, and then write code that actually does those things. If you can’t write code well in the first place, you’ll write terrible tests, and then even more terrible code to make them somehow succeed. I’d argue TDD has value in the first case, but most teams are more like the second variant.
- nostrademons 7y agoThis all assumes that you know what "the things you want to do" are. In my experience, coding is the easy part, and pinning the relevant stakeholders down on what they want coded is the hard part. If you're an employee, the hardest part of your job will be in a.) understanding what'll make your boss happy and b.) communicating how to make that realistic. If you're a B2B business, the hardest part of your job is figuring out a.) who your customers are and b.) what they want. If you're a B2C startup, the hardest part of your job is identifying a market with lots of people who want your product. If you're a maintenance programmer where these things were hammered out a decade ago, then TDD can be a godsend. If you're working with an excellent business analyst / salesperson / cofounder who can hammer these issues out with enough precision that you can trust their answers, TDD is helpful. Neither of these situations describes the gaming industry, nor a number of other very lucrative industries.
- splittingTimes 7y agoI only know some of Blows talks. Is there any written advise from him?
- rumanator 7y ago> Also I think TDD is frankly ridiculous; I've seen many teams spending more money on gold-plating test lines of code than actual code. I don't see your point. You'd still have the same problem if you had a team gold-plating some other code instead of doing their job. In fact, without TDD your problem is far worse because you don't have checks in place to evaluate if some code works as expected.
- WrtCdEvrydy 7y agoI like to do TDD (Test Driven Debugging). I have found it to be a bit lackluster for development (we write the feature, then tests up to 100% as snapshots), but for debugging there is nothing better than replicating the bug with a test, making a small change we believe to be the correct answer, and it works (or it doesn't).
- rhizome31 7y agoI call this DDT (Defect-Driven Testing) :)
- rumanator 7y agoIt's still TDD but a specific subset: issue/bug reports instead of feature requests.
- ehnto 7y agoThat's why I deploy straight to production. Crowd sourced QA testing! </joke>
- 0x445442 7y agoIt's actually not that far fetched. With some environments/orgs it's really next to impossible to test any other way than to push a canary release on some small set of users and start monitoring the logs.
- UglyToad 7y agoGlad it's not just me. While in general the advice on duplication is reasonable I think it tends to get taken too far and the example is a poor one. Presumably for now Mexico applies a different sales tax % but there are so many unknowns on how Mexican tax rates differ that I'd keep the method separate until I'm certain the abstractions are similar, otherwise you might end up with: calculateBill(locale, appliesExemption, exemptionRate, regionalTaxRate, nationalTaxRate, clothing Untaxed) Premature abstractions seem worse to me than some duplication. Besides something like bill calculation should have loads of tests.
- rightbyte 7y agoTrue story. Dogmatism is really bad always. If copy pasting into 10 almost identical functions seems resonable just do it. Atleast it obvoius that the code is a mess and that is not hidden in deep abstractions.
- ehnto 7y agoSometimes the requirements just demand lots of arbitrary but similar code, and chasing elegant abstractions is a waste of time and less robust than the nearly duplicate code blob.
- wool_gather 7y agoAgree, but please leave a comment to that effect so that I don't come into the codebase long after you've left and waste the same amount of time refactoring only to reach the same conclusion! :)
- rlonn 7y agoYou should have written that article, I think. As another pretty ancient developer, I agree with more or less all your comments. I think pair programming has its occasional uses, but that's about the only thing I'd add to the stuff you've written. Silver bullet thinking is a big warning sign, and advocating some shiny tech generically (e.g. TDD) means " go somewhere else for advice". I really like this article, for advice on how to write code: https://bit.ly/33fb94w https://bit.ly/33fb94w ("write code that is easy to delete, not easy to extend"). Copy-paste is definitely a useful practise, at the right time and place.
- mihaaly 7y agoagreed! all rules have limits, even the copy/paste one. nothing substitutes accuracy and labor.
- hutzlibu 7y ago"There are no golden rules, it's just hard work." But there are good and bad principles. Like avoid copy paste. But I would never say, never copy paste code. I do, when I hack something together quickly and if it stays it needs later refactoring. No problem there .. only if the refactoring part gets forgotten bugs sneak in. Also the advice of less is (usually) more. Witing code is easy. Writing good code which is working, readable and maintainable is hard. But as little as code also goes against readability. So like many others here said .. dogmas are stupid. There are different szenarios and just use what works for you.
- surds 7y agoNot a fan of the concept of TDD as is, but I have adopted it as the approach to bug fixing. Usually I start with reproducing the bug in specs, with at least one or more specs failing due to the bug. Then I go on to fix the bug and see the specs turn green. I think TDD is pretty well suited for the use case.
- charwalker 7y agoCopy/paste of code might have saved my team some work. We had 2 versions of the same tool built by a third party like 10 years ago that works within a major application the business uses heavily. One version of this tool had been rebuilt with a 64-bit version. The other has ceased working at all on Windows 10 which we are deploying to all users on new computers. They are functionally the same tool beyond one config file setting defaults and another config file managing access to components of the tool. After playing with the differences, we iced the broken app and updated the setup KB with the config differences. As we upgrade the core app that the vendor tools work within, we are glad this headache had a quick fix but is being cut as the new version of the application natively supports what the tool did in the old version. That being said, don't use this as a reason for doing that or at least document that for the future owners of the tool so we don't waste what little time we have troubleshooting functionally identical software.