
TDD isn't dead just because DHH can't do it - prajjwal
http://rubylove.io/2014/04/24/TDD-isnt-dead-because-DHH-cant-do-it/
======
t4nkd
So, was this meant to be a counter point to DHH's article in any way? I really
just got that you're mighty pissed that RR Parley banned some of your posts.

Dually, DHH didn't say TDD was dead, he specifically said "TDD is dead /to
him/".

Really, I think the most important take away even for people who disagree, is
this: > I don't think that's healthy. Test-first units leads to an overly
complex web of intermediary objects and indirection in order to avoid doing
anything that's "slow". Like hitting the database. Or file IO. Or going
through the browser to test the whole system. It's given birth to some truly
horrendous monstrosities of architecture. A dense jungle of service objects,
command patterns, and worse.

I'd like to see someone form a well constructed argument for why that
statement is inaccurate, over-stated, or otherwise unfair instead of just
ranting about how trying to disagree with what DHH posts ends up putting you
on the receiving end of a bunch of zealous admins.

~~~
twerquie
> I'd like to see someone form a well constructed argument for why that
> statement is inaccurate, over-stated, or otherwise unfair

Here's his statement again, rewritten without the Fox News-style
editorialization:

"Test-first units lead to a graph of intermediary objects in order to avoid
doing things that are outside the scope of your test. This practice isolates
the piece of code you are testing, but as a side-effect means that you don't
do unnecessarily slow work like hitting a database, filesystem or web browser.
It has given rise to new patterns of application architecture such as a
service and command layers."

Oops, I wrote all the same facts but stated them neutrally, and now it doesn't
sound like a horror movie! How am I supposed to bully Rails devs into
following my style?

~~~
SEMW
> Here's his statement again, rewritten without the Fox News-style
> editorialization

And here's me applying your own technique to that sentence: "Here's an
editorial rewritten without the editorialising". You then feign surprise that
that doesn't leave much.

DHH's point was that the resulting graph of intermediary objects is (in his
experience) overly complex - the implication being that, where possible,
simple is better than complex (which, yes, is a value judgement).

~~~
twerquie
DHH does have a point, but he makes it in a manner that is hyperbolic,
accusatory, narrow-minded, stubborn and often rude. I find him to be a
negative voice in the community and a dangerous leader. I am happy to fight
fire with fire where necessary, and agree with the tone of the article linked
by the OP.

~~~
otikik
> hyperbolic, accusatory, narrow-minded, stubborn and often rude

Plus:

> fight fire with fire

Seriosly.

~~~
twerquie
Sure, why not? See the "asshole vacuum" scene in HBO's Silicon Valley S01E02.

------
bulte-rs
I don't agree with DHH on most of it's design decisions (but who am I, I don't
have the same 'track record') but I do agree wholehartedly with his opinion
voiced in his rant/"article". Sure, the title is a flamebait pur-sang for TDD
zealots.

Like Slackwise said below; TDD isn't dead but everyone considering it as a
silver bullet should scratch their heads... twice, and rinse and repeat.

> YOUR code is hard to test BECAUSE you don't TDD.

<downvote mode on> YOUR code is hard to understand due to high levels of
decoupling; overuse of abstractions and refactorings for the sake of code
beautification. But at least it's tested! <downvote mode off>

------
rubiquity
This post has nothing to do with the title. The content of the post clearly
shows that the writer is upset that the way he is expressing himself isn't
acceptable in somewhere like the Ruby Rogues Parley.

I'm a member of the Ruby Rogues Parley and I saw your posts. The combination
of you swearing a few times and calling people out for "TDD challenges" is
what made people flag your post, not because of your ideals. People on the
parley _respectfully_ disagree with each other all of the time.

~~~
hderms
Every once in a while I'm reminded of the negative side of the ruby community
that people always talk about. I'm not entirely sure why there seem to be a
ton of highly negative and highly vocal people giving it a bad name, or if
it's even anything other than my selective bias, but it is really unfortunate.
For every Matz and Jim Weirich there seem to be ten Ruby rockstars who think
the best way to make a name for themselves, or have their argument known is by
being the biggest bully.

Are other communities like this or is it more pronounced in the ruby
community?

~~~
chadcf
It honestly seems like it's more prominent in the ruby community, and I'm not
entirely sure why. Part of it may be that ruby is so expressive and nice to
work in that it ignites people passions, which can be good or bad... I can
say, however, that years back when I was trying to get into ruby from PHP,
people like this gave me a very negative view of the ruby 'community' and were
the biggest obstacle I had to embracing ruby.

------
joeldidit
I strongly believe software needs to be tested, and that tests need to be
written to avoid repeating yourself (or screwing yourself over) later on, but
trying to write such tests using a TDD approach absolutely destroys my ability
to think laterally and creatively and come up with new effective approaches to
problems.

If I'm working on something that I've already done, then TDD may work alright,
but if I'm doing that rather than searching for some library or code I've
already written, then I'm failing already. If it's something simple, then TDD
is also not a problem, but at that point I'm really wasting my time.

TDD stunts design, thinking, and refinement ability, and only works when there
is nothing left but execution. In my mind, as long as the tests get written
(and obviously makes sense to write them at around the time the
function/method/class is written), then I'm alright. Also, I usually don't
know what a class will look like until I've written it, used it for a little
bit, tested it manually, etc. If I were to write a test for it prior to this,
then I'd be wasting time. I don't know how people are able to write these
tests, and separate everything out beforehand. I'm not comfortable or
satisfied with what I've written, until I see it, play with it, test it
manually, then use that data to go back and smooth out and refine what needs
to be.

I'm wondering if this is an MBTI judger/perceiver issue, with judgers being
more able to wire their minds into that of a TDD'er, while perceivers see it
as fundamentally problematic.

------
mu_killnine
To quote The Big Lebowski:

"You're not wrong, Walter. You're just an asshole"

The author gets all riled up about being banned for his 'challenge of DHH',
when (if this post is any indication) its likely his attitude that got him in
hot water.

------
Slackwise
> YOUR code is hard to test BECAUSE you don’t TDD.

TDD isn't dead, but it also isn't a silver bullet.

~~~
HeyLaughingBoy
Exactly. What all this foaming at the mouth ignores is that it is very
possible to do "TDD" and still accomplish nothing useful.

I've seen tests that for all intents and purposes _will never fail_ because
they are testing the wrong thing. Write a huge method that has numerous side
effects, but only test the return value? Essentially useless!

~~~
MaulingMonkey
Indeed. There are plenty of things that are hard to usefully test.

Multithreading code? Enjoy using TDD to ensure it has no livelocks, deadlocks,
or missing memory barriers leading to reordered operations. Especially if it's
inlined in multiple contexts...

Graphics code? Needs to look similar (but not necessarily exactly the same)
across a wide range of OSes, underlying APIs, GPUs, and driver versions - plus
many of the same concerns as multithreading code.

Cryptographic code? Well, perhaps heartbleed could've been caught ;). But all
the well intentioned MD5 unit tests in the world won't make it useful (in-
context)...

~~~
hderms
I'm not a TDD adherent in any way, but depending on the language you can get
some interesting results with automated tests and concurrency. Erlang has a
number of applications which automatically reorder the scheduling of the
various processes running in order to (hopefully) ensure the code doesn't die
when run concurrently. This is much easier to do in certain languages (ruby
obviously not being one of them).

Then again, traditional livelocks, deadlocks and improper use of memory
barriers aren't really the problems that you would face at the level of
abstraction that Erlang provides.

~~~
MaulingMonkey
There's also tools like CHESS to do that kind of thing in Microsoft's
ecosystems: [http://research.microsoft.com/en-
us/projects/chess/](http://research.microsoft.com/en-us/projects/chess/)

------
fit2rule
TDD rocks if you do it well. You know what? NoTDD rocks if you do it well,
too. There is no 'one true method' for development life - conditions change,
and you have to be prepared to apply the right process according to the nature
of the task.

If you're building something that has to be safe, say .. a life-critical
system - you better be damn sure you are testing absolutely every single
thing. Everything.

If all you're doing is setting up another hipstersite on the interwebs and
hope to have a few million groupies soon, well .. maybe you can avoid the
tests, and just wait for the support mails. That's also a valid way to get
things done - if it works for you.

------
coldtea
> _DHH does not need to be held up like a treasure or someone to emulate
> unless you want to be a handsome with a big attitude and a nice car and
> loads of money._

BS ad-hominen's like these probably exlain why his comments were hidden and he
was banned after 6 posts.

And that's the peak -- the rest goes downhill:

> _Personally, I want to write craftsman quality code. I want to explore using
> academic practices like functional programming to make my code cleaner
> still._

I mean, seriously? It's 2014, nothing academic about functional programming
practices. This kind of talk doesn't grow confidence in the poster's vast
knowledge of the field, and deep experience.

------
morganherlocker
In my experience, TDD and unit testing is awkward and uncomfortable when
working with application code, since you often find yourself simply testing
dependency wrappers, which has limited value. On the other side, integration
tests are kludgy and uncomfortable when working with library code. "Round peg,
square hole" and all that. I often see two sides arguing for a universal
testing strategy, when the use cases are very different.

I try to treat tests as nothing more than repeatable artifacts of whatever I
was trying to do to verify the code I was writing was working. So if the code
was primarily aimed at hitting a bunch of web services and making DB calls,
then the tests will end up as integration tests naturally. If the code is
doing a bunch of isolated calculations, then it will probably be unit tests.

This is a classic case of developers talking past one another and trying to
force their use case on others in my opinion.

~~~
hderms
"nothing more than repeatable artifacts of whatever I was trying to do to
verify the code I was writing was working" I really like this way of looking
at things, and think I might adopt it myself. It's kind of a nice way of
saying "test the interface", but more like "test the interface of the code
exercised by the primary consumer of the interface".

------
brudgers
Synopsis:

Pay to play discussion bans person for trollish posts following requests for
better behavior from moderators in reaction to previous trollish posts. By
logical inference this banning proves that intelligent discussion which admits
the possibility that TDD has shortcomings is nothing but cargo cult hero
worship of a technically inept has been and that TDD is the sole true
religion.

Commentary:

In my opinion, this is why hell banning may be better for cases where there is
not a shared set of standards between moderators and posters. The loss of
audience is not so apparent immediately and the lag time means there is less
likelihood of immediate escalating reaction while the poor behavior is still
spotlighted. Hell banning also offers the possibility of readmission should
behavior change with the retention of identity.

------
geebee
The best way to convince people to write tests is to remind them that they are
already writing tests, but they're throwing them away. If you're writing a
method, you are almost certainly testing it with a bit of code to verify the
output. You're probably writing one of these little tests every 5 minutes.
Save them in a folder called "unit tests". Are you writing code to make sure
one part of the API works with another? Save it in a folder called
"integration tests". Opening up a browser to make sure the right stuff is
appearing on the right part of the page? Save it in a folder called
"functional tests". Put in a code coverage tool to make sure you're calling
all the code you've written in a test - personally this usually happens when I
"got rid" of code without actually getting rid of it (rot).

I mainly work in Ruby and Rails these days, and I'll concede that it all gets
a little blurred (and I did plenty of handwaving in that previous paragraph,
but you couldn't see it because I was typing). But as long as you're doing
something like that, I really do think you'll end up with a well tested app
with full coverage.

TDD? Well, sure, I've done it, but I'm not going to insist on it, for myself
or anyone else. You could write that integration test first, or you could
write it iteratively. You could write a functional test that makes sure a bit
of text is present on a web page, and then write the the code that generates
that bit of text, or the other way around. I don't see it making a big
difference - other than that forcing people to write the test first can be a
mental intrusion that badly disrupts their thinking process on certain types
of tasks.

In spite of all that, I (like a lot of people on HN, regardless of where they
stand on TDD) would welcome a compelling rebuttal of DHH's recent blog post.

------
lukasm
Your code is not hard to test because you don't do TDD. There is a different
rule:

python -c 'from subprocess import *; print Popen(["python", "-c", "import
this"], stdout=PIPE).communicate()[0].splitlines()[-3].replace("explain",
"test")'

Yeah I know it's ruby thread :)

------
skittles
I think TDD is good when writing something you've done a few times before ("I
know exactly how to write this app"). I tend to get projects that require
exploration. I refuse to write a bunch of test code for each new class knowing
that I might delete the class later.

------
efdee
Ad hominems seldomly make for a constructive argument.

------
gaelow
'I possess the only truth and you need to prove me wrong not the other way
around'.

I witness this so often I'm starting to believe it's the motto of the software
industry.

The drift to fundamentalism about TDD over the last years is just another
example. TDD is a good methodology that can save time and improve code
quality, but only if understood and performed correctly.

That means more unit tests does not equal a better design and easier to
maintain code base produced in less time. Better unit tests, testing non
trivialities and accepting the limitations of unit testing does.

You cannot possibly test all states on a sufficiently complex, non trivial
program constantly evolving to better fit its users' needs as they are
discovered and redefined. And that's not the basis of TDD: Outlining your
design by identifying its fundamental parts and writing tests for them before
implementing them is.

Back to the main topic, I have seen people rant about version control systems,
integrated developing environments and all kinds of tools and procedures
involved in the software development process: They all take a few good
arguments and stretch them to irrationality.

For example: how can somebody like git and HATE mercurial, bazaar... Maybe you
prefer one or the other and you have your reasons, that's alright: Different
tools for different people. But am I a dumb person for having different
preferences? And if I'm not, does that mean you are dumb? I've seen pretty
dumb things done by developers using every tool/methodology, including myself.
Usually the reason is their lack of experience and understanding, much more
often than using the wrong tool/methodology.

TDD or whatever, once you learn you'll do fine. But don't be an asshole and
blindly criticize people who prefer doing it differently, even if you are the
smarter one. Specially if you are the smarter one. And just because you don't
understand a tool or methodology (yet, or ever) it doesn't mean people using
it are dumb, that's all I'm saying.

TDD has been proven effective. TDD hasn't disprove all other effective
approaches out there. Specially the ones yet to be discovered by less arrogant
people.

------
why-el
Well he said "TDD is dead long live testing" didn't he? I don't even agree
with David on some parts but but you can't write a rebuttal based on half a
title.

------
matthewrudy
Ruby and Rails are far bigger than any one person, and the types of apps many
of us build today can be far more complex than Basecamp.

Saying that though, digging into what DHH said, he was really just arguing for
pragmatism and the testing pyramid. He just used the wrong words to express
it.

Let's be craftspeople, let's use the right design patterns, let's decouple our
apps and test the right bits in abstraction, but let's also be agile and
pragmatic.

------
davexunit
This is turning into quite the flamewar. It's like Vi versus Emacs. I applaud
DHH for challenging the TDD zealots and stirring the pot a bit.

------
nothiggs
The more things change, the more they stay the same...

It seems people always have a tendency to worship something, to let the means
become the end or what is supposed to be their servant become their master.

TDD is a tool to ensure software quality. If TDD works for you then great. If
you can achieve the same results with another method it's just as great. But I
find the religion wars over it quite silly.

------
tatqx
OT but I think that there is a place for a new programming language designed
around making testing and TDD easy. Maybe the test code can be written in a
higher level DSL or dialect of the same language.

------
otikik
It's not the arguments he uses, it's his tone. He's basically temperamental
and irrespectful.

I agree with his points, but I would also have banned him.

------
qwerta
I think author is just in wrong community. Some modern strongly typed language
would suit him better. Hell even Python would do.

------
heeton
The original title should stay :)

------
PeterWhittaker
tl;dr: Acronyms, abbreviations, anecdotes, and rants do not an engaged
audience make.

Skip this and find a conversation with more substance, less flame, and less
smoke.

