Ping-pong programming (P3) is an offspring of two well-known extreme programming practices: pair programming and test-driven development. These practices by themselves promote intra-team knowledge sharing. But this is extreme programming, and we like to push the envelope, right?
I experienced a precursor to P3 when I visited Object Mentor in 2002. I was attending their Java Language Immersion and I was the only student of Micah Martin for the entire week. We had a great time. As we began working through the payroll exercise, Micah started by writing a test and sliding the keyboard over to me. I then tried to make it pass. At first, I took giant leaps ahead of him, coding far more than it took to get to a green bar. He patiently watched me as I stumbled around, often getting lost down rabbit holes. Periodically, he drove for a moment, doing something absurdly simple to get the test to pass.
I started getting a feel for how easy it was to take small steps. And I started to enjoy taking as small a step as possible, which led Micah to write more rigorous tests. This felt like a great way to combine pair programming with test-driven development. I took the technique back to work with me and immediately tried it on my XP pilot project. It was met with mixed reviews. Some programmers resisted the idea that they would be writing tests while someone else did all the coding.
Fast forward to the summer of 2004: my first project at ThoughtWorks.
Aslak Hellesoy had just joined our project. One fine Michigan morning, I had the good fortune to pair up with him. After a quick analysis of our task, he whipped together a brief test case and we watched it fail. Aslak slid the laptop over to me and prompted me to pass the test. I smiled, wondering whether this technique had spontaneously popped up on different continents (Aslak was based in the UK). I quickly passed the test and slid the laptop back to Aslak. He immediately slid the laptop back and prompted me to write the next test. I struggled to pick up on where he was headed with the first test, but eventually slid the laptop back to him with a failing test.
We followed this cycle all morning. It was an awesome way to work with and learn from an exceptional developer such as Aslak. This back-and-forth style of development became the standard way we developed together on the project. A few weeks later, I was once again fortunate enough to pair program with another exceptional programmer: Dave Astels.
The task ahead of us was not an easy one. We needed to integrate most of the tasks I had completed during the iteration, tying them together in two different contexts. After we had acquired our ritual morning coffee, Dave started us off with a test case [ping]. I was feeling a little grumpy (and lazy) and I passed the test by hard-coding the value with which Dave's mock object was expecting to be called. Then I wrote a slightly more rigorous test in order to force Dave to implement the code that he had tried to get me to write [pong]. He chuckled (as if to say I was in over my head), whipped together the necessary code, and wrote the next test--lickety-split [ping].
The morning went by very quickly as a rhythm developed in our pings and pongs. Any time either of us passed a test we looked for opportunities to remove duplication or make our intentions more explicit in the design. There was a curious mix of competition and collaboration. And then, quite suddenly, we were done. The design was so simple it almost felt wrong. I was proud of it.
In December 2004 I rotated onto another ThoughtWorks project and introduced this back-and-forth development technique to my first pair-programming partner. The thought occurred to me that naming this technique might make sharing the concept easier. After blogging about it, I discovered on Ward's wiki that it is called ping-pong programming.
There are certainly many programming scenarios where this style of development might not be appropriate, but for the several teams that I've worked with, it has provided some helpful structure to our pair programming sessions. I know there are some bored pair programmers out there, staring silently as their partner drives for hours on end. If that's you, consider giving ping-pong programming a try.
For someone who loves games and competition, the rhythm that develops in these programming sessions feels like home. When it's working right, it is competitive and collaborative at the same time. As you compete to take ever-smaller steps, you are collaboratively and incrementally building up a rigorously tested set of barely sufficient objects.