
Test-driven development: A great idea hiding behind a terrible implementation? - kiyanwang
https://itnext.io/test-driven-development-is-dumb-fight-me-a38b3033280c
======
Illniyar
He's right, but also wrong. It really depends on what you are developing.

TDD is awesome when fixing bugs (as opposed to writing features), when writing
straight up business logic (especially when there are a lot of edge cases) and
when you know exactly how something is going to work.

It's really bad when doing anything that requires exploration and research
(which is the example in the article).

~~~
moksly
I work for a Danish municipality and we buy quite a lot of development from
various software houses. Being the public sector we track and benchmark almost
everything, and we actually have a dataset on automated testing that’s been
running for two decades.

It’s hard to use the data, because we’re comparing different projects, teams
and suppliers but our data shows no advantage in choosing the companies that
are very test-focused.

They are often slower, more expensive but have the same amount of incident
reports as the companies which tests less or doesn’t do automated test at all.

~~~
Pamar
One question: are they somehow more efficient in answering to an incident
report?

My conjecture: I am not so surprised at these having the same % of failures -
after all the TDD will not magically lead everyone to think of all the
possible ramifications; you write tests for the case that you can "imagine"
just like a non-TDD developer will implement logic to cover cases they can
"imagine". But on the other hand, if after fixing the bug you need to prove
that you haven't caused some other side effect, then having a full test suite
in place should be more efficient than retest everything again (or less risky
than "ok, fixing module W _should_ not impact X, Y and Z, so we test X only
and ship...").

~~~
tempguy9999
Why is this downvoted, it seems like a good point.

Also @moksly's point seems at odds with an apparently highly regarded piece of
software, SQLite.

~~~
y4mi
most projects can't move as slow as sqlites development does.

A software such as sqlite is in the rare situation that stable releases are
more important than anything else.

Everyone I've worked with got payed for features though, not stability

~~~
tempguy9999
I guess these are good points. The last line especially.

Yet it's obvious to me that correctness and stability should be features, and
more fundamental than all others. It's not as if a non-extreme amounts of
testing is all that expensive.

------
purple_ducks
Great to see the author tackle such a broad topic after 3 months of bootcamp
and 1? year of professional development.

Regurgitating others' opinions and making multiple unfounded assertive
statements is key to demonstrating he has already mastered the software
domain.

~~~
djrobstep
The experiences of beginners are as valid as anybody else's.

It creates an unfriendly culture if people are told they can't talk about
their frustrations and challenges without having x years of experience first.

~~~
Insanity
The experience of a beginner with a certain tool is quite important. E.g, if
Linux is not user friendly to newbies something could be done about that.

But some tools require expertise and a beginner might not get the entire
picture yet. E.g, if someone with 1 year of physics experience claims Quantum
Mechanics to be dumb, is that a valid opinion?

~~~
okl
It might be. Your point is that it's not worth your time to consider that
someone's opinion.

~~~
tjpnz
I'm not going to take any opinion seriously with a headline like that.

------
Gehinnn
There clearly are problems that are suited very well for TDD and others that
aren't.

I guess the suitability of TDD depends on how much a feature involves "how"
rather than "what": Whenever it is clear what the feature should do (and what
the feature's interface looks like) and the implementation is only about the
"how", TDD seems to a very good idea. Almost every compiler-related task falls
into this category. I just wrote a blog article on how to implement Typescript
refactorings using TDD ([1]) and I don't think anyone could argue against
using TDD there.

If the feature is more about "what" (like UI/UX), TDD seems to be more of a
burden than an useful asset.

[1]
[https://blog.hediet.de/post/implementing_typescript_refactor...](https://blog.hediet.de/post/implementing_typescript_refactorings_with_hot_reloading)

------
qznc
One important aspect of tests is to derive them from requirements. Not from
the implementation. This is also true if your requirements are only implicit
in your head.

TDD ensures this as there is no implementation yet when you write the tests.

It also implies the changing requirements comes with the overhead of changing
the corresponding tests. This is what happened in the incident described in
the article. In many cases development speed might be more important than test
coverage.

Still worse are tests derived from the implementation (usually to boost done
coverage metric) because they often break although the code fulfills the
requirements.

Rule of thumb: Test only the requirements which are stable.

------
xthestreams
Regardless of my opinion on the topic, which I don't have:

why must software engineering be mainly opinion-based? Why can't we have
objective facts, or at least only talk about objective facts without going out
asserting one's opinions as truth?

AFAIK other engineering disciplines do not suffer from this problem as much as
software engineering. This really bugs me.

~~~
tadzik_
Well call me crazy, but imho the reason for that is that for the most part,
software engineering is not engineering. We're not fighting laws of nature,
we're fighting other people's style and decisions. That's why our work is
opinion based: we're basically computer lawyers.

~~~
irundebian
Software engineering may not be an engineering discipline but in theory you
could set up empirically studies/experiments to test certain hypotheses of
software development practices. In theory you could also review or evaluate
design against certain criteria and derive what's better to fulfill certain
goals.

~~~
tadzik_
Absolutely. And I think there were actually studies on the effectiveness of
TDD, and I seem to recall them confirming it.

------
gtirloni
Not much to add except that when j tried TDD, I had to have this mentality of
typing out code as fast as I could, going back to the test, fixing stuff, back
to code, learn the mistakes, etc.

While my dev approach is more about think, think, think harder, code, compiler
barely complains, fix small issues, write test, done.

TDD felt very uncomfortable because the thinking part didn't seem to be
emphasized much. It's like keep going, you iterate again real soon in this
code, now again, and again.

Maybe I got it wrong, I don't know. But I share the author's frustration.

~~~
johnmarcus
I'm with you and the author on this.

------
DanielBMarkham
"...I never understood why it was better to do things backwards...The idea
behind TDD is that you’re able to write a test because you sit down and think
about things first...."

Yeah no. You have been instructed poorly. It's not your fault.

Yes, you have to think about things, but that's not the real purpose of TDD.
Just like making a good design, it's a side effect.

Straight coding is doing it backwards, as odd as that sounds. The reason is
that the computer never lies, but it's really, really easy to lie to yourself,
forget things, misunderstand your own variable names, and so on. When you're
coding, you'll make all kinds of errors. The computer will not. So wouldn't it
be better to have the computer constantly checking on you to see if you're
making any new errors? Better still, not only will it check on you, it'll
check on everybody else who touches the code too.

There are domains in which TDD does not make sense. Exploratory coding, like
you'd do in startups, for instance. Small pure functional code. Academic
learning. _In each of these cases you are still doing TDD, it 's just you're
not coding the tests_. You never get away from TDD, you just sometimes hide it
or pretend it isn't happening. There's a test, it fails, you write code to
make it pass.

In other cases, such as any non-trivial mutable OO commercial code that is
going to be around for a while, not using TDD is malpractice. Whatever small
hit you may take on initial productivity is insignificant compared to the
endless amount of money you may spend later on maintenance.

Plus, I'm not so sure it's inefficient to begin with. Instead, I think a lot
of coders code in an inefficient way writing code that is difficult or
impossible to test. Once you start using TDD, you're going to have to come to
terms with that and un-fuck your code. That's probably going to suck. Best to
do it earlier rather than later. (Long discussion here about what to do with
legacy codebases)

------
eterm
I'm generally inclined to agree, test coverage is good, but test driven
development is awkward. I think there's a tinkerer's mindset which is very
much stifled by TDD.

I think TDD does shine for some things, it especially shines for refactors
(where the tests ideally shouldn't change anyway) or bug-fixing where you can
write in a test to catch the bug that has been found as a regression test
before starting to fix the bug.

For brand new features it is a signifincant discomfort. I concede that that
discomfort can result in more thought-through code but it can also just put
off the implementer into not working as efficiently as they would be able to
in a 'code first, then refactor' mindset.

~~~
lolinder
On the flip side, "code first, then refactor" is only safe if you have tests
to confirm the validity of the refactor, and in my experience, a TDD mindset
is the only thing that ensures I have thorough tests by the time I need to
refactor.

That said, it sounds like my version of TDD may be different than a lot of
others. The tests I write before coding tend to test real-world logic and
requirements, in terms of the domain language, rather than testing
implementation. This means I can refactor everything behind that DSL-like
facade and my tests give me assurance that I haven't changed the logic.

If your tests are at the implementation level, I can see how a TDD approach
would impede refactoring and eliminate tinkering. If refactoring the code
means rewriting the tests, then your tests aren't protecting you, they're just
getting in the way.

------
polytronic
I concur! Additionally to the article I believe the overall problem with
software development is that it cannot be done by everyone. Developing great
software requires the mentality of a passionate artist and a lifetime
dedication. Unfortunately most companies I've worked with (with very few
exceptions) are only after immediate profit and thus creating toy programs
mainly by means of integration of ready-made third party libraries. The
example they set for new developers is catastrophic. Fewer and fewer people
dwelve into the depths of knowledge. Shallow integration, adoption of over-
hyped immature components and the new trend of containerization is a two-fold
failure: a) Failure of educating minds to think and b) low quality end
products for the users with all the consequences this brings (aka performance,
security, UX, etc). It really feels as if software development has entered a
dark era where instead of educating people we create mechanics that take
'experinments' to market asap and disguising them to look like they operate
error-free. Of course such tactics cannot keep problems hidden forever. If
only I could share with you the stories of large heap fragmentation I've heard
over the years on production server code...

------
bluesign
This is skipping the purpose of TDD actually, TDD is basically binding your
every code change to a test (basically it is a spec) You are supposed to write
the minimum required code to satisfy a failing test. Basically it is kind of
commenting every bit of your code with a test.

So every line of code you are writing has to have a purpose, and later on when
you are fixing a bug or adding something new, you are making sure, you didn’t
break any previous functionality.

~~~
to11mtm
And yet when an oracle dev comments on HN about the test suite we all gasp in
horror...

------
investologia
This comment in the original article is really to the point:

I think one of the biggest values of TDD is it teaches developers how to write
unit testable code, which, if you are new to unit testing, can be quite hard
to get your head around.

As for its usefulness in ‘real-life’, I’m going to answer with a solid ‘it
depends’.

Anyone who dismisses it is missing out on some potential big advantages,
anyone who is a 100% TDD zealot is probably either wasting time or lacks
extensive real world experiance.

------
swiftcoder
I tend to think that the biggest flaw with TDD is that it assumes you have
requirements, from which to derive test cases.

And In 7+ years of engineering at FAANG companies, I've never once had clear
requirements before the software was complete (let alone started).

------
sorokod
One claim TDD makes is that a reasonable architecture arises from from its
basic approach. To me this is an extraordinary statement of which I have seen
no proof.

~~~
twic
TDD doesn't make that claim, because TDD is not a thing which can make claims.
_Some people_ make that claim about TDD. Those people are indeed mistaken.

As someone who thinks TDD is useful, i find those people particularly
infuritating, because such an obviously silly and easily disproven claim turns
the programming public off TDD for no good reason.

~~~
sorokod
It is implied by the minimalism of the red-green-refactor mantra.

------
je42
A couple of things to mind when talking about TDD.

1\. Tests can be unit-test, integration-test, e2e tests. Don't limit yourself.

2\. TDD is a technique. Depending on the problem and your experience it might
not be the right one to efficiently get you a working program and a good test
suite.

Remember there is no free lunch.

3\. Also, if you have never successfully applied TDD: Please stand stil for a
moment. Some techniques require practice and TDD is one of those.

You need to invest time in order to use it efficiently. Once you do it, you
will be faster and deliver higher quality code for a large set of programming
tasks.

4\. There are tasks where i don't use TDD. However, I usually go back to it as
soon as I can. You can switch between the two techniques. There is not one way
that is most correct.

5\. Also, note: if you don't write tests first. Writing tests after the code
is complete is more difficult. You might need to adapt your code to make it
testable.

6\. If you write tests afterwards, usually you will accidentally omit tests
for crucial cases if you are not careful. I use line coverage and branch
coverage tools to help me when I don't develop test driven.

------
gilbetron
Testability, Performance, Readability, Maintainability are all vectors we can
judge software by, and while they are not orthogonal, they are also rarely
colinear. TDD optimizes on Testability to the expense of the others. This is
rarely a good idea.

------
jomkr
Development is the ability to deliver/ship the things that increase your
business metrics, consistently.

Sometimes the right thing to do is TDD, sometimes the right thing to do is to
ssh into a production server and modify a Perl script.

------
tegiddrone
It's painful when I come to a project and the process for developing a feature
is...

    
    
      (1) install database (or point to dev,) configure app, run seed data. 
      (2) creating the state in the database manually. 
      (3) change lines of code for feature
      (4) reloading app, navigating through to the feature state, manually verifying. 
      (5) fix runtime errors or bugs
      (6) Repeat as needed. Commit.
    

We don't need to swing around the entire stack to craft some pixels or make
sure some message is displayed under specific circumstances. How do we get
developers to think beyond this workflow?

I think TDD at the very least is a education/comprehension exercise in
abstract thinking which will discourage scenarios like the one described
above. Once someone is able to TDD and 'gets it' then sometimes the way they
approach arranging code even without TDD is better. I think this is why we may
have mixed messages like "TDD is great!.. but we don't practice it at work."

Using a test harness any sorts to test something in isolation will speed
things up. We can better understand where a module begins and ends (i/o, side-
effects.) Develop it rapidly in the harness and then a few (automated)
integration tests at the end. It doesn't have to be a TDD-specific testing
harness.

React Storybook is an example of a UI test harness. It's still manual testing,
but we get that great separation-of-concerns goodness that makes for better
designed (and easier to maintain) systems.

------
honkycat
TDD is so tragically misunderstood. I don't think this dude knows what he is
talking about.

Case in point: you don't have to write your tests first. You can write a quick
spike first to feel out you API, then rewrite that code with TDD.

Why is this dude so desperate to have this function written quickly? This
whole episode could not have taken more than 20 minutes. Sloppiness is the
enemy with software development.

"But in real life, features are way more complex than Function X should take a
name and output a greeting with that name. Often times the product request
will change mid-work, or you’ll realize that the feature can’t work as
requested. Maybe your original understanding was flawed and you have to start
over."

Smoking gun right here. This is just wrong and stinks of amateur. Features are
almost always made of many small functions that do little bits of easily
tested work. And if you factor you code well, which is a large benefit of TDD:
having well factored code, changes should not collapse you whole sand castle.
If that is happening, maybe go back to school. Oh wait, you never went to
school, just a 4 week course so you can have low level programming job to toil
at...

What he is missing here is the alternative: a big ball of mud with giant
functions and poor tests to validate behavior.

------
fagnerbrack
TDD is one tool in your toolbox. You can easily solve problems like this one:
[https://itnext.io/you-dont-know-tdd-691efe670094](https://itnext.io/you-dont-
know-tdd-691efe670094).

However, there's a myriad of other problems TDD doesn't help you, like when
you need to design a system beforehand or you want to make an educated jump to
a solution that's good enough and you already know it.

------
maaaats
I have learned and used TDD before, but I don't _do_ TDD. I am, however glad I
learned it, as it influences the way I write code now to the better. (Think
more before I start writing, for instance, and writing smaller testable units
of code up front). Much in the same way learning a new programming
language/paradigm also can change how you write code in the old language.

------
JofArnold
I don't think I have a good enough to brain write all but the simplest code
without TDD. I specify what I want, write the tests, then figure out how to
make it pass those tests. Thanks to libraries like @testing-library/react this
approach applies as equally as well to when I'm writing babel AST parsers and
custom languages as it does to developing a user interface.

------
exabrial
My experience is that tdd only works when the requirements are super clear

------
ajeet_dhaliwal
_What’s far easier is writing your code, manually doing some QA tests, and
then writing automated tests that mimic those situations, specifically for the
code you wrote._

This is the most popular method of doing things in my experience and the
reason for that seems to be it makes chronological sense to a human brain.
It’s very unnatural for people (including clever devs) to consider a project
like manufacturing a car and starting with ‘the tire pressure should be
correct’. Also too often (wrongly or rightly) prototypes often don’t have
tests and that sets the tone quite early. Automated tests should be written
ASAP no matter which methodology is used.

~~~
gls2ro
This type of order will most probably get the developer into confirmation
bias: writing the tests that show the code works.

The best for me is to thing about how would I test if the solution will work,
then implement the solution and then run the tests. This why I try to
compensate a little for comfirmation bias.

~~~
ajeet_dhaliwal
That’s no so bad since automation is highly useful for regression testing.

------
karmakaze
As stated tests are important, what varies is the style and ordering of
writing them.

I don't like brittle tests that are specific to the implementation, such as
assert that such-and-such isn't invoked--an equivalent function can be invoked
and pass.

The order I do things:

    
    
      - think about the problem space, come up with some shape(s)
      - list the test cases, but don't write the bodies
      - code the happy path and runtime errors for others
      - write the test bodies, make them pass
      - clean-up any remaining placeholders
    

Sometimes (2) and (3) are flipped, more often interleaved

------
euske
As with most software engineering tools and practices, the context matters.

I'd imagine that TDD is good when you know exactly what the requirement that
the project has. i.e. TDD is good in the implementation phase but not the
design phase. In the design phase, you often don't know exactly what the
problem really is, so you need to keep things as loose as possible because
you're going to experiment. I imagine that in many small business scenarios
these two phases are often fused together, so TDD wouldn't appeal that much
for them.

------
aussieguy1234
TDD is an interesting concept.

Anything you write as an engineer has to be tested. Manual testing is way
slower than automated testing.

I find that when I have a few good automated tests in place, especially in
browser selenium tests, I save literally days of work of manual testing. Thats
time that I can use to build more features, get more feedback on my product or
do other more productive things than manual testing.

10 minutes of time writing a good test saves me days of work in the future
testing new changes. Writing good tests is a high impact, time saving
investment.

~~~
goatinaboat
_Manual testing is way slower than automated testing._

It’s entirely a matter of perspective. I consider writing a unit test to do
something the compiler could check for you if you were using a statically-
typed language to be “manual testing”.

~~~
AstralStorm
Manual testing is where you click buttons on a device and observe results.
Even that can be automated most of the time.

Pointless unit testing is a separate thing.

------
shakna
> If a coding style turns out to be great in theory but not practice, let’s
> keep the parts that work and toss the rest. My convoluted point is: There
> are lots of ways to code, we need to stop holding any one of them up as the
> “best” way.

I think this is the crux of what the authour is trying to say. Not necessarily
a criticism of TDD, but rather a criticism of holding to a particular belief
no matter the circumstances. Of being inflexible.

~~~
hnlmorg
I don't disagree with being flexible when needed but the counterargument is
that flexibility can sometimes be used as an argument for corner cutting. For
example when you start to make a few exceptions for TDD it then becomes easier
to make more exceptions; if you're not careful you can quickly end up in a
situation where your rational is "we don't have time to write tests" or worse
yet "can't be bothered to". The point of methodologies like TDD is they force
people to follow the best practices even when it's easier not to simply by
mandating a standard process.

~~~
shakna
> The point of methodologies like TDD is they force people to follow the best
> practices even when it's easier not to simply by mandating a standard
> process.

I don't disagree with that, and I don't think the authour disagrees with that.

It's when the mandated process interferes with working in the actual world.

A better test-pipeline in the article's example might be, "We don't merge
without full test coverage of changes" rather than "We must have a test before
we've explored how a spec should look".

If the standard makes the real world overly difficult, then it will cause
people to try and cut corners. It makes the developer seek to do the wrong
thing.

There's nothing inherently wrong with TDD or a bunch of other processes. There
is a problem if you're pushing yourself into a corner where you find yourself
fighting the process rather than solving the task that needs solving.

~~~
hnlmorg
> A better test-pipeline in the article's example might be, "We don't merge
> without full test coverage of changes" rather than "We must have a test
> before we've explored how a spec should look".

This is very much the rule I prefer to enforce as well. Though I do really
like the TDD approach when there are defined specifications or refactoring
happens. In those situations it can sometimes even speed up development
because once the tests are in place you then have a tighter "write, test,
repeat" cycle.

However I do still agree with all the points you've raised.

------
tjpnz
TDD is just another tool. I don't use it all that often but there are some
situations where I know it works. I have for example found it very helpful in
verifying and later addressing issues in larger codebases. There are other
approaches but they often make the root cause or causes of an issue harder to
locate. I really hope the author reevaluates TDD as I think they're doing
themselves a massive disservice.

------
lolc
About the only time I consistently code the test first is to reproduce
defects. It's really useful in that case. Sometimes that also works for
features.

When designing an interface I like to write usage examples. They're more
nimble to work with than tests who require scaffolding. The usage examples do
tend to become tests during implementation.

------
StreamBright
I think the driven part is bad. Using tests are fine, it should just not drive
your development efforts.

~~~
gtirloni
Sometimes you do have to make your code more "testable" on purpose though. But
yeah, writing the tests first doesn't always work. YMMV.

~~~
StreamBright
True. I just run into these situation too much because I functional style code
where there is very little internal state and try to use pure functions as
much as possible. This narrows down the code that has to be written on a more
testable way.

------
vinceguidry
I find myself TDDing code when the problem space is well-defined, i.e. I know
exactly what output I'm looking for. Last time I remember using it was, oddly,
in making a game. I wanted to build a CLI 2048 clone. Specifying that was easy
and fun.

------
eza
Everything has a cost. TDD (and Refactoring) increases the cost of
implementation (linearly), but they greatly reduce the cost of change. Without
TDD (and refactoring) the cost of change might become exponential and
impossible to catch up to.

~~~
okl
Assuming that the amount of test code is 2-4x the amount of production code,
TDD increases the cost of change by 2-4x when change is most likely to occur:
at the beginning of development.

~~~
eza
Agreed, it increases linearly. But now think about the cost of change without
tests. The longer you wait to introduce the change the more you will have to
change (increases exponentially). If this code was fully tested and maybe
refactored (isolated) when the need arises, the cost of change would almost go
to 0 because you would only have to implement a new feature without touching
the old code.

~~~
okl
You assume that changing a software that has tests is free, which is wrong.

Your previous-to-last sentence applies equally to a software project with or
without tests.

------
dimitar
Is there a way to read this without creating an account in Medium?

~~~
kchamplewski
[https://outline.com/2cNZTz](https://outline.com/2cNZTz)

Alternatively incognito or no js should do the job also.

------
thrax
Write the least amount of code that will solve the problem, then write the
least amount of code that will make the feature as efficient as possible to
your ability.

------
Vkaric
Reading this article got me thinking that the problem isn't TDD it self but
the interpretation of it from a specific programmers perspective. One other
poster noted that TDD is great when you know what your inputs and outputs are,
ergo a toy function/project but I disagree as a programmer you should know
that for every function you are writing before you start writing the function
since you need to settle on return type(it's true for loosely typed languages
too) so I'd conclude that maybe the OP is misussing the TDD paradigm

------
RobertoG
It seems to me that software tests is like checking if an architectural design
is structurally stable.

It's dumb to do that when you still don't have the characteristics of the
space where you are building or the materials available, but it's dumb not to
do it when you know exactly what and how you are building it.

In the same way, it's dumb not to do it when you have already a building and
you are going to start to change things.

I think the problem is that, being all information, in programing those phases
look the same but they are actually very different.

------
acd
The point is to have tests.

What came first the chicken or the egg?

Either the test came first and the code after or the code came first and test
after.

An issue can arise in fast agile test driven development environments if you
develop the code first and then do not get time to do the tests. If you start
with the test you will be ensured to have time to write code otherwise the
software will not work.

"The muscle doesn't see what you're holding in your hands." Arnold
Schwarzenegge \- The tests doesnt care how you got them in place

~~~
mytailorisrich
Requirements come before implementation.

In many organisations it often happens that the test team implements tests and
is ready to test a feature before the dev team has actually implemented it.

IMO, that's the basis for TDD, really. When you start coding you should know
what the result should be and thus you should write tests first to capture
this and guide implementation.

------
ykevinator
I agree that writing tests before code is unrealistic, but love tdd. We have
nice weekends because of tdd.

------
dfilppi
TDD of course forces you to build modular mockable code. For me it encourages
a short term thinking, hacking approach. I think it elevates unit testing a
bit too far conceptually, but it does encourage better construction. Like the
author implies, it's a useful way to think, even if you dont do it.

------
cdent
In my experience, if you find that you're unable to do TDD with a problem
you're trying to solve, then you've probably not decomposed the problem
enough. In your mind. Step back. Think.

The rush to produce code, now, is making working in this industry suck.

~~~
elyobo
I find that writing _something_ can help me to get a feel for a problem.
Start, then sitting back and thinking about it, helps me to move towards a
better solution faster.

Of course, I don't always do the stopping and thinking part...

~~~
pandler
> I find that writing _something_ can help me to get a feel for a problem.
> Start, then sitting back and thinking about it, helps me to move towards a
> better solution faster.

That summarizes the struggle that I have with TDD. I guess you could argue
that I’m doing TDD wrong, but most of the time I feel like I don’t know what
I’m going to be writing until I write it.

Basically most of my coding I feel like I’m prototyping until I iterate a few
times and arrive at a solution I’m happy with and understand where the
boundaries between various functions need to be. Until then, how am I supposed
to pre-empt my solution with tests?

------
amriksohata
I am more a fan of behaviour driven where the behaviours are written using
specflow or cucumber almost like acceptance tests. Then the developer writes
code but the behaviours are validated by the business analyst or product owner

------
jpswade
TDD is less about writing tests and more about the approach.

Just having an understanding of TDD and holding it as an aim will ultimately
result in a better, more maintainable codebase.

So what's the downside?

------
cjfd
I don't think saying anything negative about test driven development is a
positive contribution. Our industry should practice it more instead of less. I
do it almost all the time. Sure, there are a few exceptions. It is quite
unneeded for at throw-away script, obviously. If something is in a user
interface and it is purely visual it may be better to write the code first
because the browser in your head might not be good enough to write a correct
test beforehand. Those are the exceptions, though. For any program containing
somewhat complex logic TDD is king. There is nothing that beats it in terms of
reliability and after some time also regarding speed because in the end
nothing costs more time than something that keeps breaking in production.
Thorough manual testing is also quite expensive in terms of time.

I note some people here are talking about things that require exploration and
research as a counter-inducation. Well, maybe in some cases but certainly not
in all. One could also start with a test at a relatively high level and then
do the exploration while writing code to make it pass. In that case one would
write more code to make it pass than would be normal but it still benefits
from being in the TDD cycle. After having it basically working one does
additional TDD cycles to iron out the cases where it would go wrong.

The main benefits of starting out with a test is that: 1) tests do cost time
so you need to recoup that by going faster in other parts of development. If
you start out with the test it immediately starts paying back when it flags
your first attempt at an implementation as either passing or failing. 2) The
fact that the test first should fail and fail in a particular way tells you
whether your thinking about how the system works is actually correct. It is
like bringing the scientific method to programming. People in practice very
often have just the wrong idea of how something works in the first place.

People are also talking about TDD being a strange order to think about
programming. This is also my experience. It requires some getting used to. It
is quite good though. The point being that it enables one to not need to think
about everything at the same time. When writing a test you think about the
functionality you need. When writing an implementation you think about
algorithms and when refactoring you think about code quality. In traditional
development this gets rolled up in one big ball of mud which makes the
thinking about either of these three aspects of lower quality.

One thing that people get into trouble with is trying to write test for
functionality that is too low level and therefore very much implementation
defined and therefore subject to change. I think one should generally work at
a level where one tests the behavior of a cluster of a few classes. This
problem also leads to tests that are too trivial. If one has a method that
adds n to m and one writes a test for that one is testing that the processor
really can add numbers and that is not very interesting.

------
kissgyorgy
TDD is not dumb, just there are use cases where it fits better, specifically,
when you know the exact inputs and outputs beforehand and how it will fit in
your system. When designing an API, it's not a good use-case for TDD at all.
The author obviously doesn't understand that. If you don't even know what
functions will you need, you obviously can't write a test for it!

Kent Beck, DHH and Martin Fowler explain it very nicely in the "Is TDD Dead?"
dicussion: [https://martinfowler.com/articles/is-tdd-
dead/](https://martinfowler.com/articles/is-tdd-dead/)

I highly recommend it to everyone even if you think you understand what is TDD
all about! It's a very deep, interesting discussion about TDD between truly
great minds.

------
ricardobeat
The authors of this might not realize it, but a good chunk of their audience
can't read their post at all, due to Medium's paywall.

------
mobilemidget
What works perfectly for some devs doesn’t for others. That why there are
choices.

IMHO only thing dumb is developing without testing

------
kofejnik
I somewhat dislike the TDD cargo-cult myself; but this is such a shallow
opinion piece, how is it on top of HN?

25 minutes, 16 points - all that it takes?

~~~
twic
HN _loves_ shallow opinion pieces, especially when they're contrarian. They
give us a chance to wade into the comments and demonstrate how smart we are,
either by agreeing or disagreeing!

------
bjornsing
After 15 years in technology/software development my impression is that your
favorite methodology says more about you than anything else.

The sharpest engineers I know distinguish themselves mostly by how rarely they
resort to running code at all. Instead they seem to have a mental model of the
code base they are working on, similar to that of a mathematician. They can
write code for days, weeks (or even months) and just know it will mostly work
once they run it.

~~~
ssijak
Did anyone, ever, in the history of world coded for months without running the
code?

------
yoz-y
First thing: they do not define which kind of TDD they are talking about.
Second thing: without really good test coverage any kind of larger refactoring
is gambling with reliability and will bite you at some point.

~~~
gtirloni
What kind of TDDs are out there?

Don't seem fair to call out author on not writing tests because they never
said that.

~~~
yoz-y
> What kind of TDDs are out there?

I have never actually seen somebody writing all of the tests before
implementing the code even if they claimed doing TDD. Parts of tests maybe but
I think that things rarely go the way the definition is spelled out.

> Don't seem fair to call out author on not writing tests because they never
> said that.

Fair point. I have written my comment halfway into the article, the author
makes a point about tests at the end.

~~~
oriolid
> I have never actually seen somebody writing all of the tests before
> implementing the code even if they claimed doing TDD.

I had an architect who did exactly this. It was awesome, one could just look
at his code and see where it would fail because it didn't occur to him to
either test for that case or actually think what the code does. His only
explanation would be "but it passes the tests". Later he was made into CTO.

In a way, not testing for edge cases that are found during development is
quite similar to commenting on article one hasn't fully read.

------
mytailorisrich
> _A great idea hiding behind a terrible implementation_

TDD is a method.

TDD forces you be clear about what the result of your code should be before
you start coding. It also ensures that there is a test to check your code.
This is certainly not dumb.

You will write tests anyway (right?) so it does seem smarter and more
effective to write them first in the same way as you write requirements first
before writing code. Nothing prevents you from iterating as progress and
discover corner cases, for example.

People who say that TDD moves slower are simply admitting that they don't
test. Automated tests are also crucial because 99% of testing is regression
testing and that obviously cannot be done manually every time the code
changes.

I found it rather ironic that the article ends by praising behaviour-driven
development, which is an extension of TDD...

~~~
XCabbage
> TDD forces you be clear about what the result of your code should be before
> you start coding

... which is often difficult and inefficient. A large part of the point of the
article is that when making changes to an existing system, you often DON'T
know until doing some experimentation what the result of your particular new
bit of code should be. You know what change you want to happen to the
behaviour of the system as a whole, but don't yet understand how the pieces
that make up the system slot together. That permits you to dive in and try
making changes and see what their effect is, but doesn't permit you to write a
unit test right away.

> it is smarter and more effective to write them first.

But... why? You're asserting this without any justification.

> People who say that TDD moves slower are simply admitting that they don't
> test.

This accusation is pretty tedious. The article was _explicitly_ comparing the
test-first-code-second approach against the code-first-test-second approach
and giving a reasoned argument (which you've not acknowledged or engaged with)
for why the second was usually superior. The author isn't saying they don't
test or arguing for not testing.

> I found it rather ironic that the article ends by praising behaviour-driven
> development

That was sarcasm.

~~~
mytailorisrich
If you start coding before knowing what you are implementing then you have a
bigger problem than TDD.

Experimentation is not the same as implementation, by the way.

Obviously nothing is adhered to 100% of the time in real life, this is not a
dogma, but the point that you should know what the result of your code should
be before you write it and should thus write tests first (which can also help
you clarify your understanding) is eminently reasonable and valid.

> _That was sarcasm._

Article is poor overall. Sarcasm does not help.

------
GoodGOYIM
In college we were always taught to do TDD on large projects, and everybody I
know does TDD(at least here in France). I can even think of working on a
project that's not TDD. You need to look up Agile, Clean code and Xtreme
Programming ;-)

~~~
kierenj
Other than being taught it, and people you know doing it, do you have an
argument for it to share?

