
Uncle Bob on DHH: Monogamous TDD - porker
http://blog.8thlight.com/uncle-bob/2014/04/25/MonogamousTDD.html?
======
pistle
Uncle Bob, dazed, comes out swinging. Struggles to land punches, but DHH
definitely has Bob's attention.

There are cost/bene's for unit tests. There are cost/bene's for integration,
etc. etc. etc.

Cargo cult behavior and adherence gets you to where DHH makes his statements.
Inexperience with Uncle Bobology leaves you unable to cogently decide upon
structuring effective, manageable tests.

Clients' and consumer unwillingness to pay up for tests that increase LoC by
factors of 2+ mean devs need to be effective at balancing the ship cadence and
the overhead of tending the test base.

You can't blindly accrue meaningless or value-little tests. You can't always
just refactor code written to be ultimately testable.

Uncle Bob seems to pretty much only talk about tests. DHH made a larger
argument about the practicality without merely expressing simple boredom or
uninsightful consideration of the value of testing.

UBob doesn't even tread into the crux of the matter, which is that code style
and system architecture bent to the needs of testing becomes a ball of mud
(though "testable") faster than code written without this consideration.

~~~
raverbashing
"UBob doesn't even tread into the crux of the matter, which is that code style
and system architecture bent to the needs of testing becomes a ball of mud
(though "testable") faster than code written without this consideration."

Exactly that

Which makes me question Uncle Bobisms, because it reeks of lack of _practical_
experience. DHH shipped a framework that's used by several people, providing
value.

The best measure of software is _value to the user_. However, some people
think software is meant to have the nicest structures, the greatest coverage,
etc. Which are nice things to have _but they come after_ (in matters of
importance, not in time) shipping a software that solves the user problem.

~~~
kasey_junk
I think that there are lots of ways you can criticize Uncle Bob, this article,
his works etc. But saying he is inexperienced is a pretty big stretch.

~~~
raverbashing
Not so much him, but the ones who repeat what he says as gospel.

~~~
kasey_junk
You are also trying to associate TDD with religion in an attempt to make it
seem bad. This is one of the criticisms in the posting and it seems sort of
fair.

~~~
raverbashing
And then he ends with the phrase " If you aren't doing TDD, or something as
effective as TDD, then you should feel bad."

NO

People should feel bad for wrong things, not by not following some
methodology.

This is what cults and religions do, they make you feel bad for not following
what they preach.

So yeah, if you don't want to be associated with a cult, don't act like one.

~~~
parasubvert
You need to read that statement a bit closer.

" If you aren't doing <a method to verify quality day-to-day work>, or
something as effective as <a method to verify quality day-to-day work>, then
you should feel bad."

The point is that if you're not doing TDD, you should be doing something
that's as effective (or more) as TDD. Otherwise you're just doing shitty work.

IOW, you can disagree with Bob about TDD being the most effective way to
verify quality, but you still need to verify quality.

I'm not sure about you, but I think people that do shitty work should feel
bad. That's not cultish, that's just basic professionalism.

~~~
raverbashing
People have been verifying software since software was created.

Manual verification is indeed more complicated, slow and prone to failure but
it's not worthless as the TDD people paint it, not TDD is the holy grail (it
has _a lot_ of deficiencies that seem to be ignored by the TDD people)

Also, UBob is lashing other testing DHH proposes in the text, but guess what,
it's meant to test what TDD doesn't reach.

You can have 100% coverage of your tests with TDD and still have a bug.

~~~
parasubvert
"Manual verification is indeed more complicated, slow and prone to failure but
it's not worthless"

Manual vs. automated is a whole other discussion, rather separate from TDD.

Manual test scripts are not worthless, but are certainly an indication your
project is either (a) very small scale or simple or (b) going to take a very
long time to complete and be prone to regressions.

TDD is about the benefits derived _when_ you write your test case before your
code, and also the design implications of doing so.

"You can have 100% coverage of your tests with TDD and still have a bug."

Obviously. But the probability of your codebase having defects goes down
drastically with higher code coverage.

You could take the new radical approach of "don't test, just ship", but that
requires a very specific organizational culture and risk profile.

------
angrybits
The first half-dozen of those paragraphs were just him saying words, none of
them really had anything to do with the subject at hand. Kind of like a very
poor attempt at strawman arguments. "DHH accused us of being violent
extremists burninating the countryside! I have not heard of any of that
happening so it must be him using pejoratives."

~~~
mabbo
I'm not quite sure what the name of the fallacy is, but I've seen this
"technique" used often before. Make a lot of noise about the specific word or
words being used, rather than arguing a valid counter-argument yourself.

If the author had left out the first 8 or so paragraphs, this might have been
worth reading and sharing. As it stands? I don't see why it's nearing the top
of the front page.

~~~
JackFr
You don't know the name, because he's not using a logical fallacy. He's
addressing DHH's rhetorical device of loaded words.
([http://en.wikipedia.org/wiki/Loaded_language](http://en.wikipedia.org/wiki/Loaded_language))

~~~
macca321
See also the pleasingly named Weasel Words.

[http://en.wikipedia.org/wiki/Weasel_word](http://en.wikipedia.org/wiki/Weasel_word)

------
zak_mc_kracken
It's funny to see Uncle Bob take offense at being called a fundamentalist and
then follow with this gem:

> If you aren't doing TDD, or something as effective as TDD, then you should
> feel bad.

"Fundamentalist" is hyperbole, which is par for the course in blog posts that
want to attract traffic, but the sentiment is real, and Uncle Bob perfectly
demonstrates that the qualification is justified. Like most extreme advocates,
he's trying to get us to believe in something based on faith instead of facts.

"If you don't do it, you should feel bad".

Last time I heard that was in a church.

~~~
thomasmeeks
Yes, I caught that too. Bob definitely comes off as very insulted, and the
post is largely emotion rather than facts.

Personally I am so tired of hearing lines approximating Bob's statement (if
you don't do x you should feel bad) that I can no longer consider anyone whom
utters them credible. It is provably false (Linus has no reason to feel bad),
and a disservice to the entire programming community.

There is no silver bullet, stop acting like there is. Different things work
for different people.

That said, while I agree that DHH came off pretty extreme (I don't think TDD
is bad, just the overzealous proponents), I am glad that he did. It is really
nice to have another very public figure speaking with equal passion and in
utterly concrete terms to present to people whom are struggling with some
degree of impostor syndrome over their dislike of TDD.

------
bulte-rs
> If you have a test suite that you trust so much that you are willing to
> deploy the system based solely on those tests passing; and if that test
> suite can be executed in seconds, or minutes, then you can quickly and
> easily clean the code without fear.

My spider sense always starts tingling when someone says something like this.
Blind trust in an automated test-suite is a nice thing to strive for. But even
for projects in which I have every confidence that the test suite is complete
enough to actually trust it I'm still hestitant to "insta-deploy-on-pass".

Call me cautious, call me chicken, whatever... I'll not drink this flavour of
kool-aid

~~~
cyberneticcook
I think it's dangerous to rely solely on a _unit_ test suite to guarantee the
correctness of your program. Each unit-tested component may pass its own
tests, but that doesn't guarantee that by interacting with other (present and
future) components it won't exhibit any bug. I guess immutability would go a
long way forward in realizing this guarantee, but I've never had the pleasure
of working on a software where each component was truly immutable and
independent of each other.

~~~
jarrett
Very true. Here's an example of a bug that has bitten me more than once, has
everything to do with immutability, and isn't reasonably within the scope of
traditional testing tools:

A crucial class writes files to a certain folder. The test sandbox provides
such a folder, and the class knows to use that folder when it's running in
test mode. Obviously, the production environment is also supposed to provide
that folder. But oops, it doesn't!

The tests exercised writing a file to disk, the tests were all green, and the
system crashed anyway.

------
pothibo
There's something I really don't understand about all this uproar. TDD is
build test first, write software later.

So people against TDD aren't against test units. They are against testing
FIRST, writing software LATER.

We all agree that testing is part of the solution, how and when are the
subjects of discussion.

~~~
anatoly
While this is true, DHH in his article largely dismissed not merely testing
first, but unit tests altogether, explaining that he prefers to focused on
system tests. This set the tone to many subsequent reactions.

But there's no reason to tie TDD and unit testing together. Many people who
dislike TDD swear by unit tests and most of their testing code is unit tests.
They merely prefer to think of TDD as a much too extreme form of unit testing
that turns out to harm more than it helps.

From that point of view (which I share), DHH's rant is puzzling. It's like
that meme with Michael Phelps' mom. He's against TDD! Yay! Down with unit-
testing! Wait, what?

"Less emphasis on unit tests, because we're no longer doing test-first as a
design practice, and more emphasis on, yes, slow, system tests." Huh? How does
that follow? How about, let's not do test-first as a design practice, and
_still_ retain emphasis on unit tests? Because they catch plenty of bugs,
because they exercise more functionality than system tests will, because in
dynamic languages they protect you from silly type errors, because they make
refactoring merely unpleasant instead of a horror show...

~~~
jshen
This may be a confusion due to overloaded words. In rails you often write
tests against a real instance of a database using fixtures to load data, and
roll back the state after the test.

Many TDD type people will shout at you "those aren't unit tests, you must
write an abstraction layer that allows you to separate your model from the
database". DHH is conceding to their definition of the word. He's advocating
tests of the units of logic in your model, but not isolating it from a
database with an abstraction layer. Therefore, not unit tests.

------
daleharvey
This post makes me somewhat sad, I think testing is one of the least
understood and most important part of being a professional software developer,
but through university and still to today its easy to find people dismissing
it as unnecessary effort and I think a part of that is down to 'advocates' who
turn everything into an argument of semantics.

I posted after dhh's post "I think we should just stop calling them "unit"
"integration" or "system" and just call them "tests", there isnt a useful
distinction"

This post has almost 0 content and vaguelly handwaves about testing being good
in between 90% of seemingly willfully misunderstanding what dhh said.

~~~
collyw
Testing is just another tool, and should be used when appropriate. I don't
have a lot of automated tests for my application, but it is an in house app,
so I get immediate feedback from users if something isn't working. I do have a
set of tests for certain parts where it seemed to be appropriate and saved me
a lot of time when refactoring.

I was keen to put in a lot of automated tests a couple of years back, but it
was proving extremely time consuming to generate fixtures that made the tests
meaningful (and management decided there were more urgent tasks). Looking back
on it, it would have caught a few bugs, BUT not that many considering the
effort generating all the fixtures and tests would have taken.

~~~
daleharvey
I agree that its a tool to be used when appropriately, I wasnt going to follow
up talking about how advocates are often too adherent to dogma with
'everything ever should be tested'

But I still think comparative to how essential it is to a huge amount of
projects, the lack of understanding and maturity of the tools is lacking, on
all projects I work on, tests and test infrastructure is the major bottleneck.

------
tinco
I was surprised at DHH's love for capybara. I've always thought the capybara
tests as the most cumbersome, unreliable and generally superfluous tests in
our suites. They are at best slow and hard to maintain.

Together with our move from big backend rails apps to big client side apps I
think we should also be moving our integration tests to the client side.

There's some great testing runners in javascript, you almost don't notice it's
not rspec, and I think it could be much more intuitive then the in my opinion
awkward Capybara.

No bad feelings towards the Capybara people by the way, it's great software
that ostensibly has taken a lot of effort to develop. I just hope we can move
to a different solution.

~~~
gavingmiller
At PetroFeed (the app I'm building) we started out with a Capybara test suite
to exercise our client side code. I've found Capybara tests were hard to
write, difficult to debug, and brittle; often flapping on our CI server (or
worse locally). We began to deprecate them in favour of js tests. The results
have been fantastic.

------
rdez6173
This is not an all-or-nothing proposition. Unit tests have their place in
protecting against regression and validating known invariants. Granted, by not
starting with a test for every bit of functionality, it's not really TDD, but
why can't we balance practicality with perfectionism?

I think that DHH was implying that blindly following the TDD methodology may
lead to worse code that's riddled with architecture simply for the sake of
testing.

I feel that using TDD for one or more subsystems may make sense. For the
entirety of a large-scale application under tight shipping constraints? I
haven't seen it work - but that's not to say that it doesn't.

What's important is that we test our code. If you need some strict guidelines
to keep you in check, then perhaps TDD is perfect. If you know that your can
get significant coverage from integration testing, then it's probably
sufficient. If you find a bug, and put a unit test in place to make sure it
never happens again - then you're likely on the right track.

------
willvarfar
So DHH is in favour of integration tests and distrusts mocking.

Google is in favour of integration tests and distrusts mocking.
[http://googletesting.blogspot.se/2013/05/testing-on-
toilet-d...](http://googletesting.blogspot.se/2013/05/testing-on-toilet-dont-
overuse-mocks.html)

What's to be said for TDD and mocking?

~~~
kasey_junk
I think you are making a false dichotomy. I am very, very pro TDD and very,
very against mocking.

The problem is that certain architectures are very hard to test without
resorting to either mocking or integration tests. In those cases you have to
weigh which is better, writing painful integration tests (or not having test
coverage at all) or changing the architecture, or in certain exceedingly rare
cases mocking.

~~~
willvarfar
Possibly, but I also think I am accurately summing up DHH's article
[http://david.heinemeierhansson.com/2014/tdd-is-dead-long-
liv...](http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-
testing.html) and UncleBobMartin's reply where both talk about TDD mocked
tests passing in seconds.

~~~
kasey_junk
I guess mocking or not mocking was not my take from either of their articles.
I thought they were both about test scope. Mocking is one way of limiting test
scope but there are others.

I'm ok with different readings of the articles as long as TDD doesn't start
automatically being associated with mocking.

~~~
willvarfar
You'll have an uphill struggle if you want to stop TDD being mocked ;)

~~~
kasey_junk
Well played.

------
parasubvert
After these essays and the scuttle on Twitter, to me this whole debate is not
about TDD per se, it's about how far you take "architect for testing".

Purists like to create a pure in-memory application or domain model with no
framework or external system dependencies, with adapter layers to isolate such
dependencies. Some call this a "hexagonal" architecture, after an essay
written by Alistair Cockburn, where your core code exposes ports to the
various external hooks, whether a GUI, REST API, database, notification
system, etc, and your TDD drives against these ports.

The benefit is that your core unit tests run very fast and allow you to move
very quickly with the core code, and to refactor things quickly. The drawback
is that your end-to-end integration and acceptance tests tend to be brittle
since they often wind up being deferred to late in your iteration or release.

DHH on the other hand built a pretty popular set of patterns and frameworks
(ActiveRecord and Rails), and really doesn't see any value with a codebase
isolating itself from those things. Layers of indirection defeat the
productivity benefits of these patterns and frameworks, and also give a false
sense of comfort with the quality of end-to-end integration.

For example, to some, unit testing with a database in the mix is a no-no. To
others, it's fine if you can make it fast and predictable (eg. Swapping in an
In memory SQL store with test data). Another example is TDD from the UI
through Selenium, Watir or Capybara.

Uncle Bob is saying actually he's fine with such dependencies if you can meet
the speed and reliability targets of a pure model. And if you can deal with
the coupling you've introduced.

To me, TDD is about whether you write your tests before your code, and that
each test is isolated from other test contexts. As long as you setup and tear
down your context quickly and reliably, you can include whatever dependencies
that make sense as part of your daily development activities. Your level of
coupling to a framework is a tradeoff of productivity today vs future
proofing.

The clear "wrong way" practiced by some inexperienced TDDers is to not design
a hexagonal architecture at all (ie. don't build clear APIs and SPIs and test
outside in!) and to mock every external dependency, testing from the inside of
your application out. This bakes implementation details into your test cases
and makes everything brittle.

------
CmonDev
There is too much conflict of interest here. TDD is a software trainers'
bread. It doesn't age and it is better to learn with someone experienced.

I would be more interested to hear what is his opinion about design-by-
contract and strict functional languages such as Haskell and OCAML.

His constant reiteration that TDD is the only way is a bit tiring now.

~~~
JackFr
You should listen to his Clojure talks. Apparently he's moved the bulk of his
development to Clojure.

~~~
CmonDev
Clojure is dynamic. Dynamic typing generally requires even more unit testing.
As far as I understand strict static languages such as Haskell can eliminate
the need for certain classes of unit tests.

------
svdree
"I have yet to see any test-driven developers flying airplanes into
buildings..."

When a blog begins like this...

------
freework
Great music comes from great musicians, not a mediocre musician following some
kind of magical methodology. Great birdhouses are build by great woodworkers,
not crappy woodworkers using a fancy $1000 drill. Great software is created by
being written by great software developers.

If you're good enough to write a test suite that is so well done that all test
pass means with 100% certainty that your project is 100% bug free, then you're
probably an experienced enough developer to write that project without any
tests and still have it work well.

I think TDD works best as a lesson.. If I were a college professor, I'd have
my students write a class project where they had to do TDD. It teaches the
students to only write code if there is a reason for writing it. Just like
once you learn how to ride a bike you take off the training wheels, once you
learn how to write software, you can leave behind TDD.

~~~
humanrebar
Woodworkers don't maintain a birdhouse with millions of moving parts for
thirty years. Orchestras do not swap out musicians in the middle of the
movement of a song.

Good unit tests (I don't particularly care about TDD itself) also serve as
awareness, organization, and communication tools.

------
mistermann
I'm trying to understand, or "get on board" the TDD (or even just hardcore
testing, TDD or not) bandwagon, but my brain is resisting.

It seems logical to me that one difference between a fully testable
implementation and one that is not, is that the non-fully-testable one would
(or could) have larger blocks of code, where logically relevant portions are
physically together, whereas, the fully-testable one would have to break up
these larger chunks into smaller methods such that each piece can be
individually tested, so in the event of refactoring, your tests can tell you
not only that there is a problem, but precisely where that problem is.

Can someone comment on whether this is true or not?

And if this is true, would there not be at least some costs (support &
"readability", at least) associated with that?

~~~
Glide
I would half agree. A fully testable implementation being broken up into
blocks that are testable is pretty much a truism. In order to construct
software that is testable it must be done in a particular way. So the
granularity of testing forces the size of testable modules of a system.

However, it's not about logically relevant or longer blocks of code. It is
more about coupling. In untestable code the coupling is usually high, one
cannot modify one part of the system without affecting another. I believe that
this is why programming to an interface rather than an implementation is a
very important concept.

So let's imagine a look at the "extreme" end of the spectrum of TDD with unit
tests where they practice ping pong pair programming (programmers trade off
writing tests and passing them) the code will likely look different. The
"testable unit" is now not only the size of a unit test (constrained to a
single class in OOP languages), but the ping pong aspect ensures that these
code would be added in a time limit between tests (just try hogging the
keyboard for half a day!). This doesn't mean that methods won't become long,
it just means that the human constraints around the problem will force it to
become a certain size.

There are some costs, but usually smaller classes are far easier to understand
and maintain. After making a codebase testable you'll usually find that the
code goes from procedural to object oriented.

------
tomstuart
DHH criticises “good tests” and “being testable” as meaningless goals; he
characterises TDD practitioners as being fixated on testing _qua_ testing,
completely focused on testability and associated metrics (coverage, ratio,
speed) in their own right, as if they blindly believe those things to have
intrinsic value.

That’s inaccurate and unfair. Testability is useful precisely because it’s an
effective, tangible proxy for other properties of software that are harder to
anticipate or recognise: things like modularity, composability, reusability
and so on.

Tests are useful on many levels, but at their most basic they provide a second
client for your implementation, encouraging you to think harder about what
each part of your software is doing and how it’s doing it. They give you an
opportunity to step outside of your immediate goal and look at your software
in a different way, from a different angle, with a different set of
priorities. This gives you more visibility on the decisions you’re making, and
that’s almost always worthwhile.

If it’s a nightmare to isolate a piece of your implementation in order to test
it, what does that tell you? Directly: it’s not very “testable”. Indirectly:
your design is perhaps a bit tangled up, and you probably could work harder to
separate concerns and isolate dependencies and think carefully about how the
pieces interact and what they individually mean, and it might be difficult to
compose those pieces in different ways later. Would you have noticed those
problems anyway? Probably, but going through the exercise of writing tests is
one way of increasing the chances of noticing them sooner, while you still
have a chance to do something about them before they become too baked-in.

In my experience TDD _can_ lead to better designs, because it provides a
simple, learnable, repeatable discipline that makes it more likely that you’ll
notice design problems sooner. (There are other design benefits too, but I’m
trying to focus on the least contentious one.)

Some programmers may be proficient enough at spotting these problems early
that they don’t get any benefit from “testability”, and some may exert enough
control over their software’s user-facing behaviour that they are able to
dodge complexity at the requirements level, but for the rest of us it’s a
useful litmus test for avoiding messy, knotted code. Being testable doesn’t
make an architecture good, but good architectures tend to be easier to test.

I haven’t seen any sensible person say that TDD is a wholesale replacement for
thinking about the design of your software, so it’s misleading to argue
against that idea as if it’s representative.

(cross-posted from [http://lists.lrug.org/pipermail/chat-
lrug.org/2014-April/010...](http://lists.lrug.org/pipermail/chat-
lrug.org/2014-April/010036.html))

~~~
stiff
_That’s inaccurate and unfair. Testability is useful precisely because it’s an
effective, tangible proxy for other properties of software that are harder to
anticipate or recognise: things like modularity, composability, reusability
and so on._

The whole point of DHH is that the correlation between testability and other
desirable qualities is not always positive, you have to make tradeoffs. Taking
testability to the extreme you can end up with a ton of anemic classes with
hardly any correspondence between the class breakdown, method signatures and
so forth and the actual domain, which for me personally is the number one goal
right after satisfying customer requirements.

~~~
tomstuart
I agree, but you’re projecting; DHH hasn’t said anything that nuanced.

He doesn’t explicitly touch on “other desirable qualities” of designs (other
than the meretricious goal of “clarity”), nor how they relate to testability.
He just makes fun of testability without exploring what it means, how it can
imply those qualities, and how to decide which tradeoffs to make.

That’s a shame, considering how many people pay attention to what he says. He
has the opportunity to promote a more thoughtful and consistent approach to
building software, but doesn’t seem interested in exploiting it.

~~~
stiff
Might be it's not in the blog post, but he gave a keynote at RailsConf about
this and that's pretty much what he said:

[http://www.justin.tv/confreaks/b/522089408](http://www.justin.tv/confreaks/b/522089408)
[http://www.justin.tv/confreaks/b/522101045](http://www.justin.tv/confreaks/b/522101045)

~~~
tomstuart
We just disagree, then.

To pick a tiny, arbitrary example from the keynote, he criticises this
method[0]…

    
    
      def age(now = Date.today)
        now.year - birthday.year
      end
    

…as opposed to his preferred version…

    
    
      def age
        Date.today.year - birthday.year
      end
    

“Is [the method with the parameter] better? Is it simpler? Is it clearer?” He
makes fun of it as though the second version is obviously simpler and clearer,
presumably because it uses fewer characters/parameters/concepts, but in
reality it’s not obvious. It depends what you want!

The first version makes it “clearer” that the method’s result is date-
dependent, which makes it “simpler” to understand how it will behave as part
of a larger system (e.g. is it cacheable?); this is a win for composability.
If you want to call it from inside another method, you’ll need to get a date
from somewhere — maybe you’ll already have the appropriate date to hand, or
maybe you’ll choose to pass that responsibility onto your caller in turn, or
maybe you’ll decide that this is the right place to reach for Date.today.
Either way, you get a chance to think about it, and to be aware of how another
part of the software is going to behave without needing to go and look at its
source code. (This argument is essentially “referential transparency is
good”.)

Now, it’s entirely plausible that you don’t care about that benefit, and you’d
rather have a shorter method that works in the easiest possible way without
regard for referential transparency, because your system is small, or this
method is hardly called anywhere, or everything else in the application is
time-dependent anyway so you don’t need to be reminded of it. That’s fine too!
But DHH doesn’t go into any detail on the tradeoff; he just makes fun of the
version that takes an argument, because it’s testable _for the sake of it_ ,
and why would anyone bother with that?

He doesn’t seem interested in exploring the situation, or in interrogating
what testability implies in this case, only in laying out his prejudices as if
they’re indisputable common sense. They’re not.

[0] Since this is just example code, it’d be churlish to point out that it’s
not the right way to calculate someone’s age in the first place.

~~~
levosmetalo
First method works just fine if I want to calculate what was his age last
year, and what will be his age at the year of 2021. The second method doesn't,
so these are not even functionally equivalent.

------
cllns
> To my knowledge no one seriously teaches abstinence only sex education.

If only this were true!

~~~
humanrebar
Bob clearly addresses this argument. Did you have something more substantive
to add?

EDIT: I'm not trolling. Bob said that serious people do not advocate that
nobody have sex. They advocate sex but within a monogamous relationship. I
think it's a good point that deserves more than a "Nope!" in response.

------
adamlett
It's a shame that the first half of this article detracts so much from what is
otherwise an interesting and well argued point in the second half of the
article.

I have mixed feelings about Robert Martin. On the one hand I admire him a lot
for coining the SOLID principles. And I think he is probably right about many
things. On the other hand, I also think he goes overboard sometimes
(especially when it comes to the S in SOLID: The Single Responsibility
Principle), and I don't think it's wrong to call him a fundamentalist.

One thing I really admire about DHH, is his "show me the code"-attitude. For
all the people who criticise Rails for not following the "correct"
architecture principles, I have yet to see someone put their money where their
mouth is at, and show us a what correctly architected web framework looks
like.

It's probably not entirely fair, but Robert Martin makes me think of the
adage: "Those who can, do. Those who can't, teach".

~~~
jonathanwallace
That's definitely not fair as, at a minimum, it is disparaging to the
profession of teaching which is a skill and art unto itself.

------
zenbowman
Ignoring all the drama, the best arguments I've seen for TDD come from the
book, "The Practice of Programming" by Kernighan and Pike. The entirety of
Chapter 6 is dedicated to testing, and is the least dogmatic and most useful
guide to developing tests for programs I have ever seen.

I think this is what happens when the authors actually come from a place where
they have prior experience developing complex and novel systems. By novel, I
don't mean writing another web app framework, just in a new cool language. I
mean doing something that didn't exist prior to you doing it.

This is why there is so much one can gain from looking at the writings of
people who made their living off actually developing complex systems, there is
a wisdom that comes from experience, and an authority that comes from actually
doing that you cannot replicate no matter how many clever blogposts or books
you write.

------
calyth83
This whole TDD discussion reminds me of the "Safety Third" episode of Dirty
Jobs.

Testing is definitely and activity that needs to be kept in mind (i.e. "Safety
Third" or near the end, Rowe mentions that it's more like Safety Always). It
shouldn't be overdone to the point that you cannot get your objective done.

In reality, there are lots of projects with insufficient automated testing.
Preaching about the TDD might sound great until you find out that putting the
test there would easily mean nothing gets done. Everyone would love to be able
to stop all work and put tests in, but that just ain't gonna happen.

Also the preachiness gets to people - it isn't like people don't know they
should write tests; it's just they also have to balance other objectives.

This lead me to think that Uncle Bob kinda misses DHH's point.

------
grandalf
Is it really necessary for Uncle Bob or DHH to resort to such theatrics when
making an argument about software engineering practice?

I think this is an interesting topic and have some insights to share, but the
dialog is so immature and ridiculous that I do not really want to participate
in it.

Note to all readers: TDD is not something you are obligated to become strongly
opinionated about. Generalization: As a software developer you are not
obligated to be strongly opinionated or snarky/hyperbolic about anything in
order to be credible.

In my case, I use TDD for certain classes of problems b/c it saves me time and
results in a faster, more accurate development cycle.

~~~
willvarfar
Did you find DHH's piece 'theatrical'? Although it led with a one-line joke, I
thought it was a solid article sharing experience.

------
DatBear
I just recently began practicing TDD... my only problem so far: >1\. We spend
less time debugging.

I often spend more time debugging. I mainly work with C#, and in Visual Studio
(2012) when I try to debug unit tests, it fails at the Assert when the call in
the Assert throws an exception... It won't tell me where the exception was
thrown in the actual code. Is there a simple way around this that I'm missing?

Edit: It seems to be working now, not sure why it was not doing what I
expected before.

~~~
mistermann
Maybe relevant?

[http://stackoverflow.com/questions/5152265/what-can-lead-
thr...](http://stackoverflow.com/questions/5152265/what-can-lead-throw-to-
reset-a-callstack-im-using-throw-not-throw-ex)

~~~
DatBear
I'm not throwing an exception though, I'm talking about like a simple
nullreferenceexception in the code, or something similar.

Edit: I got it.

------
joshcrowder
The irony is Bob opens with "you have to wonder if the rest of the post can
recover its credibility, or whether it will continue as an unreasoned rant."
but then follows with exactly the same tactic "but since 911 has taken on the
connotation of violent extremism. I have yet to see any test-driven developers
flying airplanes into buildings while repeatedly hollering: "Kent Beck is
great!", so I must entirely reject the connotation."

------
mtarnovan
"To my knowledge no one seriously teaches abstinence only sex education."

Yeah. Right...

[http://www.policymic.com/articles/86149/the-creepy-way-
fathe...](http://www.policymic.com/articles/86149/the-creepy-way-fathers-
across-the-country-are-controlling-their-daughters-virginity) be

------
fmdud
Don't like UBob or DHH. Tepid response to a tepid article.

------
gregors
What if I decide to write my Capybara tests first? <troll />

------
bloodmoney
DHH is a really good programmer and he can probably get away with things many
others could not

------
cjf4
This is just begging to be FJM-ed. If only Ken Tremendous knew anything about
TDD...

------
gzeu73
Uncle Bob was interesting 10 years ago. But the world moved on from what he's
selling. Some people bought his product, other's didn't. The truth is gray and
we need to decide for ourselves which rules to follow and which rules to
sometimes break.

Can we please not upvote this any more? Let's keep this sort of thing as an
interesting footnote to programmer history, like Joel is now.

~~~
tzaman
So what you're saying is that best development practices somehow grow old and
die? I'd love to hear what the alternatives are if you think what Uncle Bob
and Joel preach is obsolete.

~~~
parasubvert
Much of what Joel preached is pretty opposed to Uncle Bob.

I would put Joel's opinions and advice as "somewhat interesting" on a scale
where Bob Martin's advice on Agile, OOP, and testing "defined a generation of
developers".

~~~
willvarfar
Whilst the nursery generation may have been defined by Bob, and needs GC, the
perm gen like Joel ;)

~~~
mcphage
...huh?

~~~
willvarfar
Generational Garbage Collection.

