
Ask HN: Advice needed regarding TDD from programmers - supersan
I have a question for you about TDD. How important do you think TDD is to Javascript, PHP and other development in general? I want to know your own personal opinion about it.<p>1. Do you enjoy it? 
2. Have you written code without it?<p>P.S. I hardly ever see any popular repos on Github that have less than 90% code coverage and I&#x27;ve been trying to write test driven code for sometime now but I often lose interest in a few days and start writing what comes naturally. The projects I determine not to write without TDD I never finish because I find TDD esp hard in the later parts of the project where everything is coming together like Database, Socket comm, etc. In the end I&#x27;m usually skimping on writing tests because mocking classes, using spies, etc is just too much burden (I&#x27;m self employed if it matters to anyone). Is there a way to get the hang of it? Is there a good resource I&#x27;m missing?<p>Thanks for your thoughts and guidance!
======
cauterized
I've absolutely built projects without tests, let alone without TDD. They
eventually became overloaded with tech debt. That said, the wrong types of
tests can become a straitjacket instead of a support system.

I don't particularly enjoy TDD, where you write the tests first. I do enjoy
what I call test-oriented development, where code doesn't get merged without
tests, and automated testing is how you verify any changes before committing
them (though for UI and workflows you should always have an acceptance testing
stage). It goes a long way towards making me feel confident in my code; it
gives me a structured point in my workflow to consider what the edge and
corner cases might be and how to deal with them; and it often helps me catch
and verify fixes for subtle (or not so subtle) bugs much sooner and with a lot
less effort than click-throughs would.

Edited to add: you say you spend a lot of time mocking databases and such. I
usually plan to have a DB available for testing. Django in particular makes
this easy by building an empty DB scheme for each test run and running every
test in a transaction that gets rolled back so that the DB is in a known state
for the next test. Some things you may just want to use instead of mocking,
especially if they don't require running an additional process (sockets seem
like an example of that to me, depending on what you're doing with them).

For other interfaces (especially third-party web APIs), look for libraries in
your language that will let you mock requests, specifying responses. If there
isn't one, build one for re-use, use it for all your projects, and release it
open-source. That'd be a great way to earn some visibility in your ecosystem.

------
twunde
You can definitely write successful applications without tests of any sort.
However, as your application becomes more complex, it becomes more and more
likely that you'll find it difficult to make changes without breaking
something else (especially as developers cycle through the codebase). Tests
become significantly more important if you're planning on creating and
supporting projects for 6+ months

Now the good news is that you don't need to use TDD. Tests of any kind do make
a difference, even if you have to write them after you've coded up a solution.
Tests should be testing the most important parts of your application or the
trickiest parts. Tests are there to give you confidence that your code does
what you think it does AND to ensure that you don't accidentally cause
regressions. If your application wasn't built with testing in mind, use test
data or use a BDD tool like codeception.

I don't find TDD to be necessary but I do find tests necessary. It along with
automated deployment can increase the quality of your code by an order of
magnitude.

------
supersan
Thank you everyone for your replies. After carefully reading all opinions I
think that TDD is the way to go because for larger projects sooner or later it
will help me catch bugs when the project becomes complex. I also think that
the 2x effort will be worth it with easier deployments.

I was kind of giving up on TDD but seeing that almost everyone thinks it is
important (for larger projects), I will try to watch some more videos and try
to write tests for my current project (for the work already done) and tests
first for the code that hasn't started (maybe I'll add comments in the tests).
This way I can compare the two, with which approach suits me better and fails
more (i.e. catches more bugs) in future.

------
afarrell
I really enjoy TDD when I get into the rhythm, but I've found that setting up
the infrastructure can be a real barrier, especially for a language/framework
that I've never worked in.

However, I have written code without it and I frequently find that when I do
so, I very quickly regret it. Either I get confused about what precisely I'm
doing or I end up having to write tests after-the-fact and it is much harder.
The barrier is worth overcoming. How?

1) Find good tutorials and _work_ through them.

A lot of people say that the best way to learn something is just to dive in
and build something. I disagree, at least when that thing is new to you. I
find it is much better to find a tutorial that guides you through building
something the first time. It is worth asking around on twitter or on a
relevant subreddit for this. Then, don't just read--actually work through at
least a good chunk of it. Once you've done that you have some code you can
look back on when you are looking for the basics of how to set up your tests.

2) Don't worry about mocking as much in the beginning.

The purpose of mocking is to avoid having the test take a long time to run due
to the machine spending a bunch of time working on other things. Given that
you are waiting on the machine when you run your test, this is actually
meaningful. So, mocking intelligently can be a win if you it saves you that
time. However, it also has the downsides that it can take a lot longer to
write the test and it can make your test more brittle. For that reason I find
it often makes sense not to mock and just write a bunch of tests that do in
fact (for example) hit the database. This is especially a good idea with a new
language where trying to use 7 new libraries at once ( _cough_ javascript
_cough cough_ ) is going to lead to confusion.

Also note that TDD doesn't really work if the code is already written because
doing fine-grained tests for code that is already written is really hard. It
is better to do interface/API tests and put off unit testing until you are
willing to refactor the code.

Note also that there are some tasks where your tests are going to be more like
infrastructure tests and your changes won't be quite as granular as TDD
doctrine dictates. That is something you have to accept when everything is
coming together, because that is the realm of integration tests.

There is a tutorial I've written which aims to teach this alongside teaching
configuration management, though it is my first tutorial. I would love
critiques of the pedagogy and example code. [https://amfarrell.com/saltstack-
from-scratch/](https://amfarrell.com/saltstack-from-scratch/)

------
sidcool
I prefer Test driven Development rather than Test First Development. I can't
think with tests first. I do a mix of both. In the end I ensure my code has
good coverage.

