Now there is probably some of you hard core C++ programmers that are saying: But why don't you do TDD with C++. You can do that! CppUnit! I have only the standard lame excuse: I didn't think there was time enough for me to learn how to use CppUnit on such a short, and probably one-time, project. I am not using C++ every day you know!. Well, the time spent debugging could have justified that. Allthough I had probably spent at least that time figuring out how the hell to test the issues I was having. And that brings me to what I think is one of the core issues for people learning TDD. Learning HOW to test things..
I read another blog (will try to find the link, think it was one of the FitNesse guys), that talked about "stupid test". Test that test for the obvious, which you usually have in abundance. The problem with these tests are that they do not test the object as it it supposed to be used, but only test things in thought out controlled scenarios. And when you get it out in the real project things fail anyway.
There is something right in that point. The first thing you do when learning TDD is to write black box testing of one class. A standard Modus Operandum that is easy to teach people is: Write at least one test for each contructor/method/property in the class. In my opinion that only adds real value when you test fringe cases. Those are the tests that help you aviod the hard-to-track bugs.
The next thing you do is design you objects properly for testing. That usually means being more aware of the Single Responsibility Principle (pdf) and doing
Dependency Injection. This opens a whole new set of issues where you mock the objects to be injected in order to test the object. One of the pitfalls I see there is when you incect objects that doesn't behave badly. Especially if the object you are mocking out is going to be a third party object out of your control that can (and then will) fail when doing complex real-world things, or when you want your injected objects to be subclasses - probably by others. Then you will probably see your object fail in new strange and wonderful ways if you don't test for it.
I have no solutions for this issue. But I think there are points to be aware of.
- Put you effort on your objects into testing border-line cases.
- Make your "controlled" testing environment as "real" as possible.
- Make tests where your injected objects behave badly.
- Do test for your third party components in the ways that you want to use them.
Hmmm... The last point was actually one that got me thinking. Great when you dig up ideas by blogging related ideas. I'll probably be diggin into that point more later.
Now. CYA. Have a badly behaving project to see to.