I avoid the sort of training where I stand in front of sixty people, spew information, and expect them to absorb it. While that kind of training is relatively cheap, I don't believe it's cost-effective. Instead, my training emphasizes individual coaching and small group work within the context of a real project.
Learn how to use tests to drive your code.
Learn how testing reinforces good design practices.
Start knowledge spreading throughout the team.
Get your hands dirty.
Start the gradual and sustainable move to a capable code base.
Background. This is a course about the increasingly common practice of writing your tests before you write the code, thus letting your tests drive the shape of the code. Such a course, I believe, needs to get across four things:
What it's like to practice test-driven design, once the code base supports it. The students should experience a pleasant style of programming so that they have a goal in mind during their day-to-day work.
That goal won't be achieved right away. It will take time before writing tests is as easy as it should be. Students need to know how to move toward their goal. In particular, they almost certainly need techniques for dealing with legacy code.
Writing tests is only half the story. The other half is using the tests to shape the code into a testable, maintainable, and extensible form. This is a matter of good object-oriented design skills and a finely-tuned nose for code faults such as duplication, methods that don't express their creator's intent, and classes that are trying to do too many things.
No one can learn all these skills all at once. So a team also needs the skills of teaching-while-working and learning-while-working. The course is organized to demonstrate and foster that skill.
Course format. Day one of the course dives right in. I begin by explaining the purpose of a Java library to store data in a flexible format. Since the library was written test-first, I can use tests as examples of what the library does.
Next, I ask for a volunteer from the audience. Together, we add a new feature from the library, perhaps two. After that's done, the class debriefs and I use that as an opportunity to give several set speeches about key ideas in test-driven design.
Students spend the rest of the day working in pairs, implementing new features. Periodically, we break for a debriefing. The day ends with a discussion of what students should expect their project life to be like in, say, six months.
For the remainder of the course, we move from the ideal to the project's reality. Each half-day, I will sit down with a new person from the team. We might try to wrap some of their existing code with tests, making it safer to change. Or we might add some new code in a test-driven style. While doing that, we'll directly confront some of the difficulties the team will have while moving toward the ideal. We'll also discover code that can be improved, and we'll improve it.
This will continue until I run out of people (including repeats). At the end of it all, we'll have a final session to discuss the path forward.
Who should attend? This course is best suited for an entire team who will be working together. It may be too expensive for me to sit together with each person. In that case, we should stock the course with opinion leaders: those people who like new ideas, who like showing them off, and to whom other people listen.
The first day is taught using Java, so almost everyone in the class should have some experience writing Java. For the rest of the course, we'll use whatever language the project uses.