I am going to adopt TDD in our team and one of the ideas I have is to review tests first. So one would write interfaces, mocks, and tests first, submit them for a code review and once interfaces and tests (think specification) are approved an actual implementation can be written (theoretically, can be done by another developer). I wonder how viable this idea is?
The Three Laws of TDD
- You are not allowed to write any production code until you have first written a failing unit test.
- You are not allowed to write more of a unit test than is sufficient to fail—and not compiling is failing.
- You are not allowed to write more production code that is sufficient to pass the currently failing unit test.
...These three laws lock you into a cycle that is, perhaps, thirty seconds long....Round and round the cycle you go. Adding a bit to the test code. Adding a bit to the production code. The two code streams grow simultaneously into complementary components. The tests fit the production code like an antibody fits an antigen.
To me this suggests that actually you shouldn't be spending time reviewing unit test code on an individual level, as there wouldn't be enough flexibility or speed in that approach to gain any of the benefit. It should be a fast process of multiple iterations. Theses iterations inform the programmer as they are writing code about the changes they are making, improving the code.
Instead review unit tests and final code submissions together. So long as the programmer understands the requirements correctly this should allow you to still have reviews (as you should of course) but keeping the advantages of TDD.
I think Tom's answer explains why TDD doesn't work well with reviewing unit tests ahead of time; unit tests become part of the implementation process in TDD, and are part of a tight cycle between testing and implementation. In other words, you can't write unit tests before coding if you are using TDD.
Reviewing Cucumber-style acceptance tests, however, makes sense before implementation starts. The purpose of these tests is to make sure that the customer / business owner and the developer are on the same page, and that should happen before implementation. Defining interfaces and reviewing them might also make sense, especially if two teams working in parallel. These should be relatively easy sells to the team.
I would be hesitant to design mocks ahead of time as well, as they will naturally be developed during TDD (if TDD is done right); however, doing mocks ahead of time could be useful for encouraging code reuse, so it's not a bad idea - just might not be worth the process pain. Developing mocks ahead of time could get some push-back from the dev team, if they don't fully grasp why they would be useful. I'd personally try this with just the acceptance tests and interfaces first, and then see if the team felt that adding mocks to the up-front requirements would help. This might mean more pain up-front if testers rely on developers to write mocks and devs aren't doing it, but I suspect it will result in more buy-in in the end. Also, you might find that good mocks are a natural result of TDD, and your testers are getting mocks without having to really push devs to create them. If it's the devs writing the mocks that are pushing for them to be developed first, then you already have buy-in and should give it a try.
In general, I'd be sure to get team buy-in on any up-front requirements. If the team doesn't want to do the work or believe that it might help, it won't work.
I hate such persons that says "This is not a Scrum", when they were asked "Hey, we have a scrum without stand-ups, so how could we do [something]".
I am going be such a nasty person when I say "That is not a TDD what you have described". The TDD has some strict rules, but is it really a big reason to follow them all? I think – no.
Nutel, the idea you presented is viable, but it depends how you will implement it. You should not be restricted to when to write the unit tests: before or after the production code. Maybe it would be better to start from integration tests? Or from the system integration or acceptance tests?
Or, maybe you do not need the tests at all, and it would be better to run the design workshops and just to discuss better what we need from the new functionality.
It depends on situation on you project.