
TDD is horrible while learning a new language - evjan
http://peterevjan.com/posts/7
======
raganwald
I'll generalize this and say that TDD is terrible whenever trying to learn new
tools. It seems to work really well when you're using the same tools you've
always used--frameworks, plugins, gems, libraries, architecture, server
stacks, whatever--and the only new area of research is the domain logic and
implementation thereof.

I'm running into this exact thing right now on a new project that uses some
tooling I haven't used before, and I'm doing an awful lot of yak-shaving. Some
of it I would have done anyway just writing code with the new tools, but
writing effective tests really does require a certain base comfort with the
tools.

~~~
tednaleid
It feels like yak-shaving, but when you're learning a new language, that yak-
shaving helps you dig into areas of the language (and it's infrastrucutre)
that you wouldn't otherwise know about. It will pay off in the long run.

Your productivity is down, but that's expected, you're learning a new
language.

~~~
raganwald
Not always the case. While it's true that my total knowledge is going up, it's
going up slowly because I'm trying to learn two things at once instead of
learning one thing and then another.

Consider someone who wishes to learn how to drive a car and also how a car
works under the hood. Learning how to steer and learning the complete function
of the steering apparatus at the same time is not as effective (for me at
least) as learning how to drive in one session with the mechanism either not
explained or vastly simplified. At another time, I can learn about steering
mechanisms and hear all about power steering and differential gears and what-
not.

------
andrewcooke
i disagree. unit tests _help_ when learning a new language, because you can
write a test for one very specific piece of functionality and then use it to
test whether you've got things right.

in the example given, don't mock out the file system, just use it. hard-code
your paths. you can go back and fix that later - what you're doing now is
getting basic tests sketched out so that you can learn.

so you're confusing "learning a language" with "writing a complete, portable
system". of course you can't do the latter while doing the former - you need
to make compromises. but ignoring tests is throwing the baby out with the
bathwater. perfect is being the enemy of good.

[and i am not just bullshitting here - last week i was learning go and this is
exactly what i did. the go getting started docs are very clear about how to
run tests, and having tests to check i was understanding really helped.]

~~~
rauljara
I think there is a middle ground. I absolutely agree with the author that test
driven development sucks when learning. But that's not to say never write
tests while learning. There's a huge different between writing some tests and
test driven development.

When learning, I often find it's most helpful to just plunge in, then when
something isn't working, go back and write tests to try and hone in on the
problem. Then more tests to make sure my solution works for edge cases. I find
this is helpful even when I'm not learning a new language, and just when I'm
trying to do something new enough that I can't see the outline in my head when
I start.

It's odd how sometimes TDD helps you break down complexity into manageable
chunks, and sometimes it front loads complexity, and forces you to solve
problems you aren't capable of handling quite yet. Whenever TDD is making me
bang my head, I tend to skip it for the moment and come back to it when it's
helpful again.

~~~
Argorak
I have the following rule of thumb: I write the test in the moment when I know
for sure how an Interface/Feature should behave.

If i know it before the implementation, I write the test first. Most of the
time, I start programming and write tests for everything that gets nailed
down. If I am in completely new ground, I start playing and do not test beyond
"run and see".

------
netmau5
I also find TDD to be rather useless when you haven't quite figured out what
your architecture is going to be yet. My general process is model -> test ->
code. If I can't yet determine my model because my knowledge isn't deep enough
yet, the tests are all garbage that will have to be rewritten anyway.

I get the argument of tests as interface specification, but I just don't buy
it. Some people may not like to model outside of code, aka UML or variants,
but any reasonably complicated system needs a high-level concept drawn up
before you can safely start pushing through individual components.

I love TDD for known problem/known solution scenarios, but I've found it to be
a pretty bad time sink for unknown solution combinations. YMMV, and I think
everyone finds their own comfort zone with TDD after some experimentation. The
big lessons for me were that [x] testing is a net time saver versus the spray
and pray code like hell strategy (yes, this makes sense before you realize
you're not a programming messiah after all!) and that taking the perspective
of a code consumer helps you write more fluent APIs.

------
joshcrews
I'm religiously devoted to TDD and understand the 'dirty' feeling that comes
from writing any code without it.

But its totally fine to learn new languages and try out new stuff without it.
TDD only needs to be enforced on code going into production.

~~~
callmeed
Do you do any TDD training/coaching?

------
clintjhill
This is a fair argument to make: "Remove unnecessary layers or complexity when
learning new languages." And I also don't TDD when learning a new language -
in the beginning.

However TDD (when done pragmatically) is actually a great way to dive into a
language. The thought process of mocking the file system is actually _where_
you learn about the language/libraries/frameworks. You have to understand
those APIs a little bit before you can properly mock them.

 _... like how do I run the tests?_ I run into this a lot when I code as well.
But I have to remind myself that I don't need a runner from a framework in
order to do TDD. Don't even need a framework.

There is nothing about TDD that says you have to use any unit testing library.
It's a process. And if understood properly and used pragmatically can be an
excellent way to learn a new language.

------
msie
Some people try to force/shame TDD on others because it's more "efficient".
"You're going to have to do it anyways." they say. Well, it's your mind and
it's your time not theirs. Only you will know what's right for you. If TDD
doesn't work out while learning a language then drop it. If it works out then
great. I'm sensing this TDD arrogance that really pisses me off. It's not the
only way to write a program. It all depends on who/what the program is written
for.

~~~
msie
In addition, I leave you with this:

<http://programming-motherfucker.com/>

------
jarrettcoggin
I think the better approach would be something to break each piece down into
something that can be ingrained over time. I find it much better to hack at a
language in a text editor and compiler first, then move towards an IDE if
applicable. Sometimes I find that I get more comfortable in a text editor and
the IDE is just more overhead than I need. I think something like this would
be a better approach:

1\. (If Applicable) How do I compile the code? What is the shortcut?

2\. How to I get something to display on the screen/website?

3\. How do I build unit tests in this language?

4\. How do I run the unit tests?

5\. Are there any tools like AutoTest available?

6\. What are the preferred source control tools?

7\. What frameworks are there? Are any of them by far the leader?

This can be expanded as far as you want to take it, but I think this approach
would make things a little easier to swallow. By focusing on one question at a
time, I believe someone would be less likely to bite off more than they could
chew before they were ready for it.

------
city41
I'm glad to see I'm not the only one that feels this way. Anytime a decent
amount of "newness" creeps into my process I find TDD difficult. I usually
resolve this by doing a spike, figuring out what I need to do, throw away that
code and then do it again under TDD.

------
locopati
Developer uses wrong tool for the job, complains on blog. When you're learning
a new language, learn the language. The code you're writing during learning
probably isn't worth keeping around anyways (it's likely non-idiomatic and
carries over habits of other languages).

Once you feel comfortable and want to write something a bit more stable, bring
in unit tests if you feel the need. I find tests great for establishing how I
want the API to be since the test is API-in-use and quickly shows flaws in
ease-of-use. But, if you're just learning you don't need that extra layer on
top of all the other things you're trying to learn.

~~~
raganwald
_Developer uses wrong tool for the job, complains on blog._

True, but isn't that helpful? There are loads of people who don't know that
TDD may be the wrong tool for the "learning a new language" job. Now they know
that if they're banging their head against the wall, it may not be them.

------
hippich
I learn new languages by writing tests to test my knowledge of new language.

------
huhtenberg
Apparently _TDD_ is a _test-driven development_.

~~~
ipsin
I had the same problem, even though I know what test-driven development is.
It's good practice to expand an acronym at least once in an article.

------
rue
I disagree. Code unsuitable for learning makes for hard testing. For a
reasonably good version, try <http://rubykoans.com>.

------
shareme
depends..

I have found that when learning a new language that if I have someone's unit
tests it makes it easier. BUT, I have a few languages of exp such as C/C++,
COBOL, assembly, Pascal, Forth, Java, Groovy, Python, etc.

In most cases, TDD is not to be used with beginners unless its used as pair
programming. In fact if you read back when TDD was established that was one of
the use cases for paired-programming..

------
MostAwesomeDude
I think this is a specialized instance of the general advice to not test code
which has not yet been written. If you're writing a test ahead of the code
which it tests, you'd better have every single line of that code already
written in your head.

~~~
gte910h
TDD has red:green testing a central principle.

You're SUPPOSED to write the test ahead of the code which it tests.

~~~
MostAwesomeDude
One is also supposed to never change the test after it has been etched in
stone, especially in BDD, but good luck getting people to follow that rule,
especially in this modern age of Agileish development cycles. TDD, if
practiced exactly as originally described, ends up being a drain on resources.
You care more about the tests than about the code being tested.

As a now-classic example, observe a TDD master struggling with Sudoku:
<http://xprogramming.com/articles/oksudoku/>

~~~
gte910h
> to not test code which has not yet been written.

You're not doing TDD if you're writing tests afterwords, you're just writing
unit tests. I'm not trying to dissuade you from that but just pointing out
you're using the wrong term if you're not doing that.

I'm not a TDD proponent for most types of work that aren't heavily interfaced
based, webservices to iPhone apps, I TDD them, but the actual app internals?
Only on certain parts.

