Pair Programming, TDD, and Rotation?

For about three years I had the chance to work in the most interesting setup I experienced in my professional career. At first it might sound complicated to maintain, but trust me, it’s not. The results speak for themselves.

Pair Programming for 8 hours per day. Working in pairs was the default in our development team, with rare exceptions such as someone on sick leave or in jury duty 1. Some might think Pair Programming is hard to achieve and questions such as “Who drives?”, “When is it the time to switch?” “What does one do while the other is coding?” are always asked when I mention Pair Programming to someone not familiar with the technique.

These questions are totally valid, and I risk to say I don’t have the answers for an environment which doesn’t do Test Driven Development (TDD). Alongside Pair Programming, TDD was at the core of our culture. When in combination with Pair Programming, TDD defines the boundaries for the driver 2, making clear the moment engineers should switch: one writes a test, which should fail, and the other the code which makes the test pass. Once the test passes, the person who just implemented the code writes the next test so the ping-pong can continue. At the end of the day everyone ended up writing the same amount of code.

While TDD helps to build better and structured code with clear contracts and interfaces 3, Pair Programming gives the chance to discuss every step of the process, from architectural to code design decisions.

In a team of 10 engineers, pairing indefinitely with the same person wasn’t an option for us. We wanted all the engineers to have the opportunity to work with each other, and in different areas of our mobile application (and Backend for Frontend, BFF). So we had rotation. Two engineers would never pair for more than one consecutive day. If Alice and Bob are pairing today, tomorrow one of them hands over the position to Carol. If Alice gives her spot to Carol on the second day, the next move is Bob switching with Dave. on the third day.

Day 1:   Alice + Bob
Day 2:           Bob + Carol
Day 3:                 Carol + Dave

The overlap is fundamental for knowledge transfer.

Which brings me to another topic: Lanes. We had lanes of work, which are closer to Epics than Missions or Verticals. Lanes implement complete features and might exist from a couple of days to a few weeks and, in most cases, are completely independent from each other. E.g., photo backup, new settings menu, mosaics to make a collage of pictures, etc…

Each engineer was in a lane for two days before jumping to another lane (thus the overlap for knowledge transfer in the example above).

The benefits are obvious. While Pair Programming with TDD makes sure engineers are delivering the best at their best, rotation makes sure they have the whole picture of what they are putting in production (from engineering and product perspective).

This setup promotes a feeling of shared ownership, where everyone is responsible for the product and technical decisions. The constant rotation also gives a chance to make adjustments to the technical choices made on previous days. It’s always better to correct the direction sooner than later, reducing technical debt.

Formal Code Review - e.g., via Pull Requests - doesn’t exist in this setup. Code Review happens in real time by the pair working on the feature, and commits can be merged into the main branch at any time during the day (and multiple times in most cases).

Having a shared ownership simplifies communication in the team, questions can be addressed by any person or pair at any time. Every engineer has all the knowledge and context to answer questions from the Product Owner, give/ask feedback to Designers, or interact with external teams. It also eliminates that feeling of “this is my code and I don’t want anyone to touch it”.

The last, but not least, important piece of the puzzle is the Pow Wow. Whenever a pair would like to discuss something with other engineers, they would call for a Pow Wow. A ceremony as simple as everyone standing up to discuss a technical decision for 5-10 minutes. No formalities, no meeting rooms nor calendar invitations.

Since we were all on the same page about technical topics, it was pretty easy to size User Stories during planning meetings. Almost three years working with the same team gave us confidence to perfectly size our 1-week sprints, simplifying our backlog refinement sessions and plannings. For our Product Owner this was extremely valuable in order to maintain the backlog relevant and prioritized.

As a result we had a fast paced and united team, sharing every aspect of the development process, delivering high quality code with confidence, releasing updates every week, and supporting the Product Owner and Designers. We eliminated time waste by doing Code Review in real time, and technical debt by addressing bad choices sooner than later.

Of course this is just part of the story, only covering our engineering ways of working. Equally important is the partnership with the Product Owner and Designers, but that’s a topic for another post.

  1. We had a list of chores in our backlog for when someone had to solo. Simple tickets with lower priority. ↩︎

  2. We didn’t use the terms driver and navigator. In fact, we didn’t have names for these roles. ↩︎

  3. I don’t see TDD as a tool to write tests, but as a framework to help me to write better code. ↩︎

Otavio Cordeiro @otaviocc