20 December 2019
ICYMI, mobileforming values things like: "iron sharpens iron," continuous learning, and teamwork. These values help us grow and become better at whatever it is that we do, and collaboration is at the core of these values. We collaborate in many ways: asking a teammate for help on a problem, participating in code reviews, building team morale during work events, etc. But we, as a team, haven't tried pair programming—at least until October.
What is pair programming?
Pair programming is an agile software development technique. The technique is in the name: a pair of programmers team up to work together. This isn't just your typical ad-hoc situation when you call someone over to take a look at your work. Pair programming is intentionally sitting together at a single workstation. One programmer drives or writes the code, and the other navigates or reviews each line of code. This can be beneficial in a number of ways. For one, working on a problem together from start to finish might reduce the time spent on fixing or preventing mistakes. The navigator might notice a bug that the driver didn't—saving time and improving code. An even more tangible reason why pair programming is beneficial is learning keyboard shortcuts. I remember learning that you can search easily on Slack (cmd + k) by watching a teammate do it while we were sharing a workstation.
We can infer or research all the benefits of pair programming, but we weren't ever going to know until we did it for ourselves. The goals for pair programming month were simple:
- Measure the effectiveness of pair programming for our team—how does it affect velocity, code quality, team harmony, bug bounce, etc.
- Identify situations where pairing is particularly effective or not effective
- Improve the knowledge and skills of individual developers by learning from each other
- Improve team cohesion—more communication and more collaboration may result in more empathy and trust
And to help those who have never paired before, Noeleen—our VP of Client Engineering—came up with some helpful tips:
- Pair intentionally for the duration of a ticket. (i.e. Decide that you are going to work together on the ticket before you start—rather than "pairing" only when you get stuck)
- Share the responsibility of driving and navigating—get ample experience of both.
- Stay engaged. Take a break if you're finding it hard to focus.
- Kill your ego.
- Communicate: listen, talk, ask questions.
- Be respectful and courteous: “Do you mind if I drive for a while?” or “How can I help?”
- Take the opportunity to work with someone you don’t typically interact with—get to know them a little better.
- Slow down—if your partner is unfamiliar with the area of the code you are working in, you may need to spend some extra time explaining things. Make sure you are working at a pace that enables you both to understand the task and contribute ideas to the solution.
- Increase pace—don't spend too long analyzing and debating.
- Trust your pairing partner and be open to their suggestions.
Over the course of the month, 24 team members paired up. Some of them paired for hours in the office, and others even paired remotely. Most of the team (approximately 66.7 percent) were familiar with pair programming. To measure our goals, we asked them to respond to a post-pairing questionnaire. Based on these results we asked, did mobileforming developers meet the month's goals?
How effective was pair programming for our team?
We asked our developers if the code quality was better than if they had worked alone. A majority (70.8 percent) answered yes. Of this majority, they explained further that working on a solution together meant they could lean on their partner or keep each other accountable. One person said,
"Having someone who knew the methodology better allowed me to start things in the right places, which meant less refactoring and less rewriting when access levels on methods and variables changed."
Another noted that "working on a solution together allows both participants to contribute to the implementation equally" which allows for more room for adjustments or alternative approaches. A few people also said they were cutting corners less when pairing. These point to pairing being effective for our team. For those who said code quality was not better, the level of quality came down to if they followed the coding standards—not necessarily the act of pairing.
We also asked if the work was completed more quickly as a pair than if they worked individually. A majority (58.3 percent) responded with no, but the explanations revealed there to be some split. A few agreed that having different expertise made it easier to fix issues: "When I got stuck or still needed to think about something my partner stepped up with a solution." However, the flip side was communication. Communication is plentiful when pairing, so that slowed things down for some of our devs: "the overhead of having two people communicating and discussing the process slowed things down." One person acknowledged that the work was completed slower, but they didn't mind it as much: "We went down more tangents (like exploring features of the IDE), so it was technically slower, but it was slower for good reason (i.e. learning)."
Based on the feedback received, it sounds like pair programming is more effective when we're not on a time crunch. Higher code quality may have lead to some time saving, but that didn't necessarily compensate for the lower number of tickets completed in a sprint. So how effective is pair programming for our team? It depends.
In what situations did pair programming lend itself to be more efficient?
The devs picked up a variety of tickets when pairing, so we could understand the context in which they were pairing.
One pair worked on a new feature that includes UI (user interface) work, integration with an API (application programming interface), calculations, and string manipulation. On how their ticket lent itself to pair programming, they said: "it was especially useful to pair program since it was building a new feature with new screens because I was exposed to how we aim to do things here in general, giving more insight to our standards." Another person pointed out that "pair programming is very good at getting feedback that you can't get from PRs [pull requests]."
Our managers pointed out that they noticed pairing is most effective when an issue is critical (two viewpoints are necessary), foundational (so the rest of the team is aligned), or easy to make errors on.
After hearing from the team and managers’ feedback, Noeleen inferred:
“It’s important to select a ticket with the right level of complexity. For tickets that were simple and straightforward, it felt more efficient to have a single developer work on them—pairing seemed to slow things down unnecessarily.
"Most developers selected tickets that required them to implement new functionality rather than bug fixes. Perhaps in part because these tickets are more substantial than most bug fixes and provide a better opportunity to get a feel for the pairing experience. Implementing a new feature together with a pairing partner seemed to provide a good learning opportunity for both participants. They were able to share their ideas and approaches to UI development or API integrations for example, allowing for good cross-pollination of knowledge.”
We knew pair programming would be a collaborative effort, but now we know how to get the most out of the experience: choose a ticket that is both challenging and worth having multiple vantage points. Collaboration is what sets pair programming on the path to effectiveness.
Did our team improve their knowledge and skills by learning from each other?
Even though most of our team had pair programmed before, we have never done it at mobileforming. This meant there was a lot for us to learn about the dynamic, but we also wanted to know if we were continuously improving our knowledge and skills as a team through the exercise.
We asked "did you improve your technical skills in any way (check all that apply)?" and we provided them with a list: "using IDE" (integrated development environment), "learned something new about the iOS/Android platform," or "learned something new about Swift/Objective-C/Java/Kotlin."
Improvements with "using IDE" came out on top with 45.5 percent, and then "learned something new about Swift/Objective-C/Java/Kotlin" with 29.2 percent. Most of the team also noted that in addition to the options we gave, there were other technical improvements with things like git commands, unit testing, graphQL, and stubbing and injecting.
Beyond the technical improvements, we wanted to know if our communication skills had gotten any better. Some responded that they either saw no change or they were already friendly with their partner. However, the majority pointed out that they learned how to ask better questions or choose words wisely.
So, did we achieve this goal of improving our knowledge and skills? This thought from the questionnaire sums it up nicely: "I gained invaluable knowledge I never would have been exposed to otherwise that has caused immediate improvement in my work as a developer."
Did pair programming help our team build better relationships?
We've said it before—mobileforming's culture is a top priority. In everything we do, we try to contribute to a culture that is innovative and cooperative. Pair programming was a chance for us to develop our culture through work—not just through after-work activities, but was that the case?
When we asked how the team felt about the experience, we found that it opened the door for everyone to learn. We encouraged our team to try different partners, so they could compare the experience of collaborating with developers of different skill levels. Because of this, our team gained insight into each other's processes, knowledge gaps, and ways of thinking. One of our devs pointed this out: "Teaching someone builds confidence in your own knowledge." Being able to teach a team member something new brought depth to the relationships we have.
Others enjoyed working with someone else for a change: "It's usually [more fun] to work with others, provided that it doesn't turn into a debate." or "it was a pleasant process, I'm definitely doing more of that if possible."
Those who didn't have a good experience with their partner struggled with slow process, arguments on approaches, or they lacked chemistry with the person. While it was a chance to learn, it did nothing for their relationships with other team members.
From this experience, we can assume that pair programming isn't for everyone or even for every ticket.
There were pairs who found it so valuable for themselves and the development:
Others didn't see it that way, but they could still recognize how pair programming might be helpful:
"I realize that pair programming may slow the sprint burn down, but I gained invaluable knowledge I never would have been exposed to otherwise that has caused immediate improvement in my work as a developer. I believe pair programming should become a regular part of our sprints, even if it's as small as one week per quarter."
"While I don't feel pair programming is an effective use of developer time, in general, it's good to have people become more comfortable with collaboration.
"Generally, it feels more useful to use this tactic in very specific situations which could benefit from multiple viewpoints, which is more likely to happen at very specific points in code work, rather than on an overall ticket."
One month of trying a new method of development was ambitious. However, the goals we set for ourselves were not only met, but we also gained valuable insight for future collaboration. We learned that pair programming was best done when the timeline wasn't rushed, and it lent itself to new feature development. It was an experience full of learning new things and improving skills, so it fit right in our wheelhouse.