My team needs to successfully implement Test Driven Development (TDD). Which techniques have you found successful in making the cultural shift from traditional development to TDD? And what checks and balances should we put in place to ensure ongoing success?
Here are some [XP] techniques that I can think of that can get you on the path, but not completely implement it, since agile is a process rather than a goal.
- Pair programming. Namely - ping-pong style pair programming where one developer writes a test, the other one has to write as little code as possible for that test to pass. Repeat until feature is implemented or bug is fixed.
- Code reviews on merges. We (in company I work at) are using git-flow for code versioning. Before each feature or bugfix is merged back to develop branch the merge request is submitted and the code is reviewed by 3rd developer (if code was written by two using first approach). Needless to say - merge requests without tests should be rejected outright.
- Code katas. Take a very well known project and reimplement it every week using TDD. Granted - the project implementation should not take more than half a day.
- Pre-commit hook to run tests before the code is checked in to blessed repository (if using DVCS) or central repository (if using VCS).
Test coverage can also be of some help but I've seen too many times when developers rely on test coverage number even when the wrong things are covered with tests. Meaning - it's better to have 70% of test coverage for core functionality (which would amount maybe to 20% of all code base) rather than 90% of all code base, but core would be only 10% covered by tests.
Continuous Integration is also an option, but this would require more discipline as after every broken build the fix should be introduced ASAP. If not - everyone in dev-team "gets used to" red dot next to project name and doesn't care much about the health of the build.
Having an automated continuous integration server is the best way to have visibility and transparency when using TDD. It allows for everybody in the organization to see that tests are being written.
If you use the branching pattern people can commit broken tests to a feature branch and then being fixed red/green refactor. The neat part is that those tests can be then be fixed by someone else in a ping-pong fashion.
TDD for everything is usually too much for a team to handle. I would recommend to start testing it on individual small stories and allow people to get used to TDD.
Finally always make sure that your stories have acceptance criteria that can be easily setup as tests. If you use the INVEST mnemonic this is a given.