When I was working in C++ and Java, I had this strange thought. I thought that much of what we were trying to do with unit testing was targeted at giving ourselves some of the benefits of a read-eval-print loop in a compiled language. The nice thing about testing is that we can get rapid feedback. A REPL gives us that too, albeit without the ability to run it over and over again.
I wonder, though, whether we can have have it both ways. A while back I did the StringCalculator Kata in Haskell, and even though I wasn't writing tests in a file, I adopted a particular rhythm of working. I typed expressions at the REPL containing functions that didn't exist yet, then I wrote them and "arrowed up" in the history to reevaluate them. It seemed to me, that if I dumped a transcript of that session it wouldn't take much work to fashion it into a set of tests. The process could even be automated, although, doubtless, you probably have to go back and edit the source: drop redundancies, name test cases well, etc.
The neat thing about a tool like this is that it wouldn't have to be perfect. And, perhaps, the user would be able to give hints at the REPL. Sort like "break here when translating to tests."
Someone has to have done this. Anyone know? I know Python has doctest but it doesn't seem to be quite the same.
Blog inspired by Mark Simpson: http://verdammelt.posterous.com/tdd-and-repl-analogies
Darius Bacon's Halp is like this - literate programming with embedded exploratory tests.
https://github.com/darius/halp
Posted by: Johnicholas | April 14, 2011 at 06:53 AM
The Python module doctest is exactly for that. You paste console sessions into files (or docstrings) and then you can execute them as tests:
http://docs.python.org/library/doctest.html
Posted by: Carl Friedrich Bolz | April 14, 2011 at 07:04 AM
@johnnicholas Thanks!
@Carl Freidrich Bolz Yes, it seems docttest is close, but not quite the same. You're looking a transcript rather than test code.
Posted by: Michael Feathers | April 14, 2011 at 07:10 AM
It's been a while since I used Eclipse, but it seems that you get exactly the effect by writing unit tests before you write the code.
Writing SQL views I use a sort of progressive refinement that has a similar 'smell.'
With scripts I often set up a shell loop with a marker file, e.g.
while true
do
if [ \! -e .marker.file -o scriptundertest.sh -nt .marker.file ]
then
./scriptundertest.sh
touch .marker.file
sleep 1
else
date +'%Y-%m-%s %H:%M:%S - no changes to script'
sleep 15
fi
done
The key thing is that your tests need to be idempotent or otherwise harmless while still giving you the info you need.
Posted by: SchemaCzar | April 14, 2011 at 07:29 AM
Very interesting point!
Couldn't one go the other direction and turn tests into something more REPL-like?
I'll often have either a test class or a single test called Scratch. Perhaps we could create a special test runner that runs continuously and, for whatever test you last changed, produces extra output. E.g., it shows the current test code plus annotations with interesting result values.
Posted by: William Pietri | April 14, 2011 at 09:00 AM
You may have hit on an explanation for why APL people said "We've been doing this TDD stuff for _years._"
Posted by: Arraymac | April 18, 2011 at 07:58 AM
That's amazing.
Posted by: iPhone contacts backup | February 10, 2012 at 12:03 AM
183 ve read through a number of the articles in your website , and I love the way you blog. I included it to my favorites blog site list and will also be checking quickly. http://www.viphandbagscheap.com
Posted by: cheap designer handbags | April 13, 2012 at 10:38 PM