I’m blogging my way through Gary Bernhardt’s excellent Destroy All Software series of screencasts. If you write software, you should probably go buy it today.
In Episode 3, Gary builds a simple version of RSpec, using TDD. I’d seen him do something similar at the Testing in Python BOF at PyCon this year, when he trolled the audience with Ruby, challenging the assertion that “RSpec is hard!” with derision and flair.
The interesting part about the screencast, then, was watching him drive his coding with tests. I’d describe myself as a “testing believer”, but I think I get tripped up at the same place a lot of people do: where do you begin? How do you know what test to write first, when you don’t even know what the call interface is going to look like?
So I found myself exclaiming as he began: “that test doesn’t do shit!” Indeed, the first test doesn’t do anything other that test that there’s this describe thing, that happens to take an argument. So the primary lesson I took away from Episode 3 was that when it comes to TDD, you’d don’t have to know where you’d end up. You just need to start.
The other lesson was that the cycle isn’t “write tests, write code, fix code until tests pass.” It’s more like “write a test, write a little code, repeat”. And there’s an additional step that I don’t always remember: re-read your previous tests, and refactor as needed.
It’s interesting watching these screencasts, and feeling like I’m learning, even though I don’t really know the language (Ruby). In this episode I learned a little more about Ruby’s blocks: the interpreter silently ignores a block passed to a function that doesn’t expect it. I wonder why that is?
I also learned that instance_eval is the core of a lot of Ruby DSLs, and runs a block as if it were applied to an instance (I think I have that right). I think the Python equivalent would be to eval some code with an instance’s dict as the local context.