[Haskell-cafe] HSpec vs Doctest for TDD

Richard A. O'Keefe ok at cs.otago.ac.nz
Thu Jun 26 23:22:34 UTC 2014

On 27/06/2014, at 12:37 AM, Alois Cochard wrote:

> Interesting, It's sounds like your definition of `TDD` is what is my definition of `solving problem`.

Not exactly.  It's problem solving/design activity PLUS
recording aspects of your decisions as machine-readable tests.
> My point was that I don't want to write test for a grammar that I might realize during further design that is wrong, this would be just complete wasted effort...

For one thing, tests can be automatically generated from a grammar.
The first time I demonstrated this to a class of students, I said
"now, here I've got this program that I wrote a few years ago and
I know it works, this is just demonstrating how you can generate
tests from a grammar."  And then the very first generated test
revealed a bug.  At that point I was Enlightened.

But the most important thing here is that a grammar and an API
are not that different.  The whole *point* of writing your tests
first is that the interfaces we design are just another of the
things we get wrong.  It's way too easy to design an interface,
code it up, start testing, and discover that something that
should be easy is somewhere between difficult and impossible,
and fixing it requires a redesign.  (I would say that the
original Document Object Model looks very much like something
that was frozen before being checked this way.  Certainly
everything *I* wanted to do with it was unspeakably clumsy.
Hooray for Haskell and document *value* models!)  Writing
test cases is one way in which "further design" happens; if a
test that should be straightforward isn't, *that* is when you
"release .. that is wrong".

None of this is new.  Back in the 1960s when people like Dijkstra
were talking about top down design, they were talking about
writing a program *as if* some helpful genie provided all the
library support you needed, *playing* around and getting the design
right, and only *then* implementing the library.  (And when doing
that, you do the same thing all over again.)

> Instead I just test as a way to tryout my DSL... but really to me it does *not* relate to TDD... because I can do the same with just a REPL and the history of it...

Using a REPL (provided your system saves a transcript so that you
can replay tests later) has two main problems:
(1) you can't do it until the code and its interface *exist*,
    whereas writing tests earlier can save you time wasted on
    implementing the wrong interface
(2) using a REPL is apt to be a bit haphazard; thinking about
    your tests off-line you can get more coverage with less work.

Don't mistake me.  I am *not* good at testing yet.  The only
reason I'm defending TDD is that I have after too many years
finally learned that "if it isn't tested it doesn't work" is
true of *MY* code, so the earlier I test something the less
horribly embarrassed I'm going to be.

> I wish that definition you use was the same understood by the industry, but it is not the way it was presented to me when I discussed with TDD enthusiast in the past... maybe things changed.

We are not called to be right.
We are called to improve.
Learn from many masters but obey none.

More information about the Haskell-Cafe mailing list