Effective pair programming requires a lot more than simply plopping two people down in front of a monitor. Both programmers need to be actively engaged in the task at hand—-something that can prove pretty tricky at times. Lately we’ve been trying out a strategy called ‘ping-pong’ pairing to find out if it can further improve our practices.
Until recently, we had three developers (Bill, Greg, and myself) working on our embedded project. With three developers, we had a tendency to pair program whenever it was convenient, especially since none of us were on the project full time. What this led to was:
- A lot of time with two people pairing and one person working on tasks we had deemed safe for soloing.
- When pairing, one person would almost always drive with the other person taking the navigation role.
This really wasn’t a great setup. All too often, the solo programmer would take on tasks that really shouldn’t have been soloed on. And sure, the other two were pairing, but the way we paired made it tempting (and easy) for one person to become bored or distracted. This arrangement was poor primarily because we violated one of our core development practices: effective pair programming. On top of that, we weren’t delivering the promised amount of paired programming to our customer.
About three weeks ago, Greg was moved off this project and onto another. Bill and I identified that soloing was dangerous, so we arranged our schedules such that we would always pair. We also decided to try out a pairing technique I had done a bit on my other project: ping-pong pairing. Sean Carley has an excellent writeup of what ping-pong pairing is. Sean’s description is succinct, so I suggest reading it. But in short, the TDD cycle flows as one person writes a test, the second person writes the code to make it pass, the second person writes another test, and then the first person writes the code. Repeat.
We’re trying out ping-pong programming in hopes that it will alleviate the temptations described above. The technique is interesting because it keeps both of us awake, attentive, and interested in what is going on; in other words, we are both actively engaged, at all times, in both the tests and the source code. It is definitely making the embedded project even more enjoyable.
One of the fun side effects of this style is that we find ourselves quite often slipping each other the ‘Kent Beck.’ In his book Test Driven Development: By Example, Kent discusses a testing technique he calls triangulation. After creating a test, when the solution in code is not obvious, he recommends doing the simplest thing possible to make the test pass. Often, this is simply just returning a constant, throwing an exception, doing nothing, etc. For example, if an object needs to perform a non-trivial calculation, often the easiest thing to do is to return the number the test is expecting. The next test will then ask for another number, forcing the code to actually perform a calculation. You continue to develop the tests and code until you’ve satisfied the expectations of the object.
When Bill and I are ping-ponging, one of us will create a test. Then the other will often try and do the ‘Kent Beck.’ The next test is written and the first programmer implements the code to solve the problem. We’ll go back and forth like this for the entire day. Taking baby steps with triangulation makes writing the code simpler and more fun. In fact, there have been a couple of occasions where we would have written more code than necessary to solve the problem; we thought we needed to implement something generic, but because of lots of simple tests, we found that the simplest solution was the best. This has been great because it forced us to implement clean code that works—-precisely what people like Kent Beck and Ron Jeffries had in mind.
Perhaps the best part of ping-pong pairing is that it has made the programming more fun. By writing lots of little tests and switching back and forth, we really push each other in a way we wouldn’t get with regular pairing. And more importantly, we push hard on the code under test, which really helps it become the best it can be.