[Haskell-cafe] Type System vs Test Driven Development

John Zabroski johnzabroski at gmail.com
Thu Jan 6 00:41:49 CET 2011

These are some heuristics & memories I have for myself, and you can feel
free to take whatever usefulness you can get out of it.

1. Don't confuse TDD with writing tests, in general.

2. Studies show that if you do TDD, you can write more tests than if you
write tests after you write the code.  Therefore, TDD is the most productive
way to test your code.

3. TDD has nothing to do with what language you are using; if you want a
great book on TDD, I'd recommend Nat Pryce and Steve Freeman's Growing
Object-Oriented Software; it has nothing to do with Haskell but everything
to do with attitude towards software process.  A language is not enough to
dramatically improve quality, you need a sane process.  Picking a good
language is just as important as picking a sane process, and the two go
hand-in-hand in creating great results.

4. Haskell's type system gives you confidence, not certainty, that you are
correct.  Understand the difference.  The value of TDD is that the tests
force you to think through your functional and non-functional requirements,
before you write the code.

5. I have a hard time understanding statements like "The difficulties in
unit testing OO code is coaxing objects into the correct state to test a
particular property."  Difficulty in unit testing OO code is best documented
in Robert Binder's tome [1], which is easily the best text on testing I've
ever read and never gets cited by bloggers and other Internet programmarazzi
(after all, who has time to read 1,500 pages on testing when you have to
maintain a blog).  Moreover, you should not be mocking objects.  That will
lead to a combinatorial explosion in tests and likely reveal that your
object model leaks encapsulation details (think about it).  Mock the role
the object plays in the system instead; this is kind of a silly way to say
"use abstraction" but I've found most people need to hear a good idea 3
different ways in 3 different contexts before they can apply it beyond one
playground trick.

6. If you care about individual objects, use design by contract and try to
write your code as stateless as possible; design by contract is
significantly different from TDD.

7. Difficulty in testing objects depends on how you describe object
behavior, and has nothing to do with any properties of objects as compared
with abstract data types!  For example, if object actions are governed by an
event system, then to test an interaction, you simply mock the event queue
manager.  This is because you've isolated your test to three variants: (A)
the state prior to an atomic action, (B) the state after that action, and
(C) any events the action generates.   This is really not any more
complicated than using QuickCheck, but unfortunately most programmers are
only familiar with using xUnit libraries for unit testing and they have
subdued the concept of "unit testing" to a common API that is not
particularly powerful.  Also, note earlier my dislike of the argument that
"The difficulties in unit testing OO code is coaxing objects into the
correct state to test a particular property."; under this testing
methodology, there is no "particular property" to test, since the state of
the application is defined in terms of all the object's attributes *after*
the action has been processed.  It doesn't make much sense to just test one
property.  It's called unit testing, not property testing.

8. If you've got a complicated problem, TDD will force you to decompose it
before trying to solve it.  This is sort of a silly point, again, since more
naturally good programmers don't waste their time writing random code first
and then trying to debug it.  Most naturally good programmers will think
through the requirements and write it correctly the first time.  TDD is in
some sense just a bondage & discipline slogan for the rest of us mere
mortals; you get no safety word, however.  You just have to keep at it.

9. Watch John Hughes' Functional Programming Secret Weapon talk [2].  I'd
recommend watching it if you haven't already.

10. Watch and learn.  Google "QuickCheck TDD" [3] and see what comes up.
Maybe you can be inspired by real world examples?

[1] http://www.amazon.com/dp/0201809389
[2] http://video.google.com/videoplay?docid=4655369445141008672
[3] http://www.google.com/search?q=QuickCheck+TDD
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20110105/2b4530ab/attachment.htm>

More information about the Haskell-Cafe mailing list