TDD + autotest = happy developers + quality code
In test-driven development (TDD), we make each test fail before we write the code that makes it pass. It’s a great practice because it helps you spot bugs almost instantly (esp. if you use “autotest” or a similar program to automatically run your tests every time you modify any code or test).
A few minutes ago, I wrote the following “failing test”:
it "won't overwrite an existing file" do
FakeFS do
File.open(house_appraisal_downloader.appraisal_dir + '/test_record.html', 'w') { |outf| outf.write("abcde") }
expect {house_appraisal_downloader.save_as('test_record.html')}.to raise_error
end
end
I expected my test to fail by overwriting the existing file and not raising an error. Instead, it passed — by raising an error when I hadn’t expected one since I hadn’t yet written the code to prevent overwriting existing files.)
To see the error, I ran:
it "won't overwrite an existing file" do
FakeFS do
File.open(house_appraisal_downloader.appraisal_dir + '/test_record.html', 'w') { |outf| outf.write("abcde") }
house_appraisal_downloader.save_as('test_record.html')
end
end
The error message pointed me straight to my goof. My code should have been:
def save_as(filename)
File.open(@appraisal_dir + '/' + filename, 'w') { |outf| outf.write("12345") }
end
But I had forgotten to add , 'w' as the second parameter of File.open!
So thank you yet again, TDD. Writing failing tests before writing the code to make them pass is a brilliant way to catch errors immediately. It simultaneously builds a large test suite that documents your code and immediately identifies future code regressions.
Posted by James on Friday, September 09, 2011