Spolsky vs Uncle Bob
The last few weeks, a dispute has been going on between Joel Spolsky and Robert C Martin, a.k.a Uncle Bob. It all started when Jeff Atwood and Joel Spolsky aired the 38:th Stack Overflow podcast when Joel mentioned that he often gets a suggestion that he should add unit testing as a 13:th thing to The Joel Test: 12 Steps to Better Code, which Joel did not agree with. Joel explains:
There’s a debate over Test Driven Development… should you have unit tests for everything, that kind of stuff… a lot of people write to me, after reading The Joel Test, to say, “You should have a 13th thing on here: Unit Testing, 100% unit tests of all your code.”
And that strikes me as being just a little bit too doctrinaire about something that you may not need. Like, the whole idea of agile programming is not to do things before you need them, but to page-fault them in as needed. I feel like automated testing of everything, a lot of times, is just not going to help you.
Joel basically have two different kinds of objections. The first one is about what you spend your time on:
But, I feel like if a team really did have 100% code coverage of their unit tests, there’d be a couple of problems. One, they would have spent an awful lot of time writing unit tests, and they wouldn’t necessarily be able to pay for that time in improved quality. I mean, they’d have some improved quality, and they’d have the ability to change things in their code with the confidence that they don’t break anything, but that’s it.
Joel’s second objection is about the fragility of the test suite:
But the real problem with unit tests as I’ve discovered is that the type of changes that you tend to make as code evolves tend to break a constant percentage of your unit tests. Sometimes you will make a change to your code that, somehow, breaks 10% of your unit tests. Intentionally. Because you’ve changed the design of something… you’ve moved a menu, and now everything that relied on that menu being there… the menu is now elsewhere. And so all those tests now break. And you have to be able to go in and recreate those tests to reflect the new reality of the code.
The discussion went on the to the SOLID principles of object-oriented design that Uncle Bob gathered, which Uncle Bob and Scott Hanselman did a walkthrough of in a recent episode of Hanselminutes. Joel again:
It’s object-oriented design, and they’re calling it agile design, which it really, really isn’t. It’s principles for how to design your classes, and how they should work. And, when I was listening to them, they all sounded to me like extremely bureaucratic programming that came from the mind of somebody that has not written a lot of code, frankly.
But Jeff and Joel didn’t do their homework on Uncle Bob coding and his relationship with agile. Uncle Bob was the originator of the meeting that led up to The Agile Manifesto and he’s been writing code for a living approximately since Jeff and Joel was born. He also writes a fair amount of his code writing in the public, so Bob posted his thoughts on what was said on the podcast.
I’m not religious about TDD. I consider it a discipline worth following. I don’t write all my tests first. Some small number of them are simply more convenient to write after the code. There is even some code I don’t write tests for at all, because it’s just not worth it. But those are exceptions to the rule. The vast majority of the code I write, I write test first. (And no, Joel, this isn’t a waste of my time.)
Bob also decides to override Joel on agility:
Joel said that the SOLID principle aren’t “agile”. (sigh). Everybody and his uncle thinks he knows what the term “agile” means. But I’m the guy who called the meeting where the name “agile” was picked. I’ve been writing about Agile development since the term Agile development was created. I think I know what is Agile and what isn’t. And I think I have the authority to override Joel on this one. Joel, the SOLID principles are agile.
About Joel’s experiences that typically 10% of the tests break when you change your code, Uncle Bob writes:
Joel went on to complain about the fragile test problem which is that as you make changes to your code, some of your tests naturally fail. Joel quoted the statistic 10%. That’s laughable, and indicates that Joel has never tried to to gain anything beyond a surface understanding of TDD (a failing typical of business wonks). If you design your tests such that 10% of them fail due to a single point change, then you need a new career. Test design, like any other part of software design, is about decoupling.
As the debate went on, Atwood wrote a blog post he called The Ferengi Programmer, where he says that even though he appreciates that the SOLID principles are not objectionable on the surface, there is a danger on relying to heavily on rulesets.
Rules, guidelines, and principles are gems of distilled experience that should be studied and respected. But they’re never a substute for thinking critically about your work.
What Jeff writes is indisputable. There will be no good software without critical thinking of what you do, and people writing books, guidelines or methods are generally aware of the risk of people slavishly following your advice without being aware of the context, but it’s not an easy thing to avoid. It all boils down the Dreufys model of skills aquisition, and what level of the skill the reader has reached at the time they read the advice. Following Jeff’s advice means that you decide you want to move from Advanced Beginner or Proficient to Competent on the Dreyfus scale on that skill. That particular move is considered something you have to do deliberately and not something that automatically happens just because the years go by.
After some more argumentation in public, it was decided that Uncle Bob should be on the air for a Stack Overflow podcast and that episode was recently aired. Uncle Bob got the chance to describe the thinking behind the SOLID principles, and Joel asked questions about when they are relevant. A small pattern evolved where Joel asks why the principle is important, Bob gives an example of being able to deploy components separately, Joel asks if this principle is only relevant in very large projects where you need separate deployability, and Bob comes off as agreeing with Joel on this one.
When it comes to quality and TDD, the differences are more clear (even though the value of tests as documentation seems to be accepted by all). Bob explained the importance of creating a test suite that is not as brittle as Joel’s experience where 10% typically break after a change, and how it can be done by separating logic and presentation and testing right below what’s shown on the screen. Jeff suggests that how it’s always been done in the Unix community where you first write a command line application and then you write a UI on top of that to drive it.
In the end of the podcast Jeff, Joel and Bob talks again about the risk of following advice and about the skill level of the programming community and they all agree that there are far too many developers that does not care about what they do. All in all, they all agree that caring is essential, but the feeling is that they do not believe in the same way of developing software. All three acknowledge that responding to change is important but how much design and test-focus you need to achieve that is the core of the differences, and that’s a difference that is quite wide-spread in the industry. Change is quite constant, but how we deal with change differs vastly.
This discussion naturally generated a lot of discussions on in the blogoshpere, and on the forums the signal-to-noise ratio dropped. A thoughtful comment that relates to learning was presented by Dhananjay Neneto as a reaction to Jeff’s post on The Ferengi Programmer. Dhananjay says:
My big difficulty with the post is that it is an advice which may do more harm to junior programmers than good. It might encourage them to make tradeoffs before they learn the cost and implications of making the tradeoffs. And it might set themselves away from a path that requires careful and judicious application (which requires a lot of effort in the early days) and helps them internalise the principles.
This debate is one that could go on forever, and a debate that normally is on a too noisy level to be interesting, but there are interesting elements here; elements that are not only a matter of taste. Several questions arise:
In what way do we get new developers to learn things that experienced developers internalized without falling over too hard while learning?
How to we cope with change and where is the cutoff point where are efforts to plan to cope for change are no longer paying back?
Are SOLID principles only valid for complex projects? When should and shouldn’t they be applied and where is the line between use and overuse?
Thanks for the summary...
Kevin E. Schlabach
Thanks for writing this so well and showing a journalistic review (both sides). I've seen a lot of the noise, and many of the pieces... but I was struggling to follow where this conversation went. You've reduced it down to the important pieces and summarized it here for history sake which will be important because you are correct that the debate will continue for months to come.
are they crazy?!
I like Joel's writing, but he's come up against pretty much an unstoppable (development) force in Robert Martin. He should do his homework.
Re: Thanks for the summary...
Kent Beck's reaction is missing
In a recent podcast, Joel Spolsky makes comments that make clear his lack of knowledge of what I do and what I say. His work has not afforded him the opportunity to evaluate the quantity or quality of my work as a programmer.
apart from that, I have to agree with Kevin.
To be or not to be Agile
This is like saying that hey I will take one structure out of your house and that will be a pillar. If you take out the pillar the whole building will collapse.
I would agree that TDD slows down the development at FIRST! but later in the life cycle of the project you will find out how much time you have saved. You can try to run fast from the start of the marathon and hope to win the race but you will most likely end the marathon if you are going at a constant speed.
Re: To be or not to be Agile
That would mean that 10% of your tests are testing the same functionality ... ouch.
100% coverage, just because?