
What I learned using unit tests/TDD - pauloortins
http://pauloortins.com/lessons-unit-tests/
======
ExpiredLink
UnitTests != TDD. Why is this confused so often? TDD is an optional variant to
write tests. The benefits of TDD are questionable. The benefits of UnitTests
are beyond question.

~~~
anon1385
It's a deliberate marketing ploy by the TDD cultists. I see the same people
doing it over and over again even after being corrected repeatedly.

~~~
skrebbel
You seriously blame a vaguely defined, unorganized group of people of
deliberate conspiracy?

A much simpler and less nasty explanation could be that to people who do TDD,
the difference between 'doing TDD' and 'writing good unit tests' is completely
uninteresting. It's all part of the same engineering practice.

This blog post clearly seems to target people with an interest in TDD, so I
don't see what's wrong with that.

------
z0r
How many of the <fixnum> benefits of TDD and unit tests are achievable through
the use of sufficiently advanced type systems? Disclaimer: I'm not using
advanced type systems to replace unit tests myself, but the more I read about
them the more I suspect that most of the tests I've ever worked with (a small
sample to be sure) could be obviated by pushing the logic they test for into
structured types.

~~~
prawks
This is one thing that has irked me a little bit as I've gotten more involved
with TDD and unit testing in general: the logic in many of my unit tests is
near duplicate logic that is implemented within my application.

My thought is that the general advantage of TDD is that you are thinking about
your eventual implementation from the outside. You write tests in a different
mindset based on expectations, rather than when you are implementing the
production code where you are more concerned with the details of logic, etc.
Unit tests also tend to be a bit more readable than the actual implementation
logic, and so act as a nice form of documentation as a side-effect. In this
way, test-first development provides a more gradual transition between a
specification or design and the end implementation, which results in fewer
missed requirements, allows for easy refactoring, etc.

This is of course only related to TDD however, not unit testing in general.
Hence, it still irks me that many of my tests look so similar to the logic
they are testing, and thus aren't really testing for correctness at all.

~~~
tieTYT
I went through a phase of this when I started writing automated tests. It
occurred when I started using a mocking library for the first time. The
library was so advanced I could basically test my implementation instead of my
api. EG: "first you call foo.bar(), then you call foo.baz()" As a result, my
test and my system under test looked very similar.

I'm not sure if you're in the same situation I was in, but let me tell you: My
situation was an anti-pattern. All I was testing was that my code does what it
does. I wasn't testing that my code was working.

Make sure you're not making the same mistake. If you are, a symptom would be
that lots of tests fail when you're only refactoring.

~~~
prawks
Not quite, but I get what you're saying for sure. I think jacquesm said it
well in his reply to me that you're more testing the "contracts between two
pieces of code right at the interface", and it shouldn't be any deeper than
that to avoid what you're describing.

The symptom of many tests failing during refactoring is something I'll be
keeping in mind, however.

------
kellros
Thanks for sharing, I agree with the points you made. The only thing I would
add is that not everything is testable in the sense of given: input, expect:
output.

A common scenario I encounter is that sometimes when you are refactoring a
method and refactoring it into multiple methods (for better readability or
segregation); that you are required to make the new (sub) methods publicly
available for testing purposes. This goes against the intention of improving
readability because now you have to expose certain methods that you would
rather haven't be called independently. In such way, TDD helps identify
artifacts with too many responsibilities.

The best tip I can think of to give someone approaching/doing TTD is to make a
check-list beforehand of what you are trying to achieve. This helps to focus
your attention on usage patterns and identify 'end-points' (end points being
testable artifacts). Just because you're doing TDD, doesn't mean you don't
have to have a plan to start with.

~~~
PaulHoule
In Java you don't have to make the methods public, you can just make them
default scope. The test cases can see them because they are in the same
package but the rest of the system can't.

~~~
prawks
I'd imagine this is similar to "internal" in C#. If so, that still doesn't
equate to being private, as other objects can see them within the
package/assembly. To the outside world this is fine, of course, however it
removes that additional organizational capability within the package.

~~~
ghswa
Solving this surely requires explicit support for testing at the language
level, eg. a "private testable" scope.

------
showsover
I must admit that I don't fully do TDD, but sometimes it helps me getting my
tests out first, so that I can "figure out" what to do in my real code whilst
running the tests.

I see the return values of certain functions and computations, and while
debugging my failing test, I can see a path to the solution I need.

Once the test succeeds, it's time to clean up the ugly code and refactor it
into clean subsections, be it functions or classes.

So yeah, TDD is a great tool. One of many in my toolbox.

~~~
pauloortins
I love clean and well-written code but to achieve clean code we should be able
to refactoring without break our code. This is the point for TDD.

~~~
_pmf_
> I love clean and well-written code but to achieve clean code we should be
> able to refactoring without break our code. This is the point for TDD.

That's also true for vanilla regression tests. There's nothing special that
TDD adds in this regard.

~~~
pauloortins
I disagree with you at this point. When using TDD we tend to do a better code
design and we avoid to write unnecessary code.

Take a loot at [http://www.ime.usp.br/~aniche/files/tdd-and-design-
draft.pdf](http://www.ime.usp.br/~aniche/files/tdd-and-design-draft.pdf)

~~~
stonemetal
_Take a loot at_

What are we supposed to be looking at there? Like most TDD literature I see a
lot of assertions, but no evidence to back it up.

~~~
pauloortins
What would be a good evidence for you about the TDD influence in design ?

~~~
stonemetal
Me personally, I would take several projects with TDD and non TDD
methodologies, control variables like team size, project size, team
experience, etc. and compare outcomes like defects rates, schedules,
performance, etc.

Try looking at SEED [http://evidencebasedse.com/](http://evidencebasedse.com/)
. TDD comes out not to bad. Quality correlates very well with # of unit tests
regardless of methodology. TDDers tend to have more unit tests. Therefore TDD
tends to produce quality code at better rates than other methodologies because
it tends to produce more tests.

------
GhotiFish

       it’s almost impossible and you will lose too much time
       but cover the majority of your code is perfectly 
       achievable. A good rule is test 
       *everything that can possibly break.*
    

but... but...

------
pbiggar
To the OP: I wonder why you didn't recommend using Continuous Integration?

[disclaimer: I run a company that does hosted CI:
[https://circleci.com](https://circleci.com)]

~~~
pauloortins
I recommend to use. But I never used, so I prefer to not talk about something
that I can't explain how to use.

But yes, I think that Continuous Integration is a good practice.

