Pairing With Developers: A Guide For Testers
By Lisa Crispin
Over my years of working on agile teams, I’ve paired a fair amount with developers. They sometimes ask me over for a “Show Me” or “Desk Checking” session as they wrap up a story. This means that the developer walks through the code they’ve written with the tester and they do some manual exploration. Teams I’ve worked on do time boxed exploratory testing sessions in pairs and sometimes groups. These sessions might seem similar to the all-day pairings that ours and other agile teams do, but they’re not.
My current team tried a new experiment: have a tester pair with a developer at least one day a week. The motivation was the move to an automatic, twice-weekly deploy to production. Despite having thousands of automated regression tests at all levels running in our continuous integration, we had too many regression failures found just before release, or in production after release.
If developers did more exploratory testing on a story before marking it finished, they should be able to catch more of these failures early. Pairing with a tester is one good way to learn more testing skills. This style of tester-developer pairing has presented many benefits for the agile teams I’ve worked on. I’d like to share some of these benefits with you, along with tips on how to pair successfully.
We’re all too busy. There’s way more testing to do than we can get to. So why spend time pairing with developers? Here are some benefits to tester-developer pairing:
Helping developers learn to go beyond the happy path in their own testing.
Having testers and developers collaborate to automate customer-facing tests that guide development promotes shared understanding and leads to more maintainable tests that provide good coverage.
As a tester, pairing all day with a developer to do the work that they normally do helps you build a much closer working relationship.
You learn the high-risk areas of the production code.
It’s a lot of fun!
Since I joined my first XP team in 2000, I’ve been privileged to work with teams where developers, and testers, pair some of the time, but many established team cultures do not include pairing for anything. If your team does pair programming and/or pair testing, you can easily take this concept further to try tester-developer pairing. If not, keep reading.
Ask your team to think of some small experiments to get you started with pairing. Start small. Pair with a developer for an hour to do some exploratory testing. Ask them to spend a few minutes walking you through the new code for a story. Try a 30 minute “group hug” where several team members in different roles test out a new feature that’s about to be released to beta. Additionally, I’ve paired with developers to write help center articles and to mind map exploratory test plans; these are great examples of small experiments to try out.
Pairing Around Unit Tests
The coders I’ve paired with practice test-driven development or TDD. As a tester, I’ve found that I can help developers specify good unit tests to guide their coding. Unit tests are used more for code design than testing, though the resulting automated unit tests help guard against regression failures when they are run in continuous integration. A tester can provide the big-picture view: "how might this tiny area of code impact other parts of the system?" By working together with your different perspectives, you’ll come up with more effective tests and more robust code.
You don’t have to write code to pair with someone who does, but some basic technical awareness will help you see the benefits. If you’re a tester, you can bring plenty of skills to the party. In my experience, testers have a different perspective than developers. We can step back and see the big picture. For example, how a change could affect other parts of the system. Generally, testers have a good idea of how people will use our software product. Developers tend to focus on the narrower area where they’re currently coding. Pairing brings these viewpoints together, helping to build the right thing correctly.
To-Do Tasks Before Pairing
Make your pairing session a more valuable experience with a few preparatory tasks:
Ask a developer teammate to give you a high-level overview of your product’s architecture. You can have them present it a number of ways. One way is to draw it out on a whiteboard. They’ll likely be happy to do that.
Learn the basics of the IDE (Integrated Development Environment) that the developers on your team use. Don’t worry if different team members have their own favorites, they are not that different, and your teammates will love teaching you all the keyboard shortcuts.
If your team’s not already pairing regularly, the infrastructure becomes more of a challenge. Ask your team to experiment, start by setting up a pairing workstation.
Successful pairing requires the right infrastructure. If you and your pair are squeezed around one monitor, keyboard and mouse, you won’t have the freedom to take control when needed.
Example of a good pairing station.
Playing To Your Strengths In Pairing Sessions
Your strength is your testing experience and skills. Think about how you and your developer pair can explore at a story level.
What source code control tool does your team use? GitHub, Subversion, there are a few popular choices. If you don’t feel competent with it, again, your developer teammates will be glad to enlighten you. Also, many source or version control tools have easy-to-use desktop apps. You’ll learn more about the tools as you pair - each person has their own preferences. And you’ll find the knowledge handy for many other purposes.
Even if, like me, you work on a team where developers pair 100 percent of the time, it’s hard to get developers to pair with someone in another role - we all have our own comfort zones! I’ve been lucky to have developers on my team who go out of their way in the daily stand-up to get me paired up with someone.
Lead By Example: Ideas To Start Pairing
Here’s an example of a way to get the team to try tester-developer pairing.
Let’s say that in your team retrospective, you discuss why so many problems aren’t found until release day, and often the release has to be put off. You agree that they are problems that could and should have been found by the developer(s) who delivered the stories. Ask the team to set a measurable goal, for example, “reduce the number of bugs found on release day by 20% in the next month”, or “no more than one showstopper bug found on production release day in the next two months”.
Suggest a month-long experiment: have each tester pair with a developer one day per week, to work on one or both of the following:
Stories from the backlog - the developers’ “normal” work.
Writing and executing exploratory testing charters on stories that have already been delivered and deployed to test environments.
At your team retrospectives (which I hope are at least once a week), evaluate whether pairing is helping you move towards the goal you set.
Get Support For Pairing
It helps if you have support from dev and test managers to experiment with pairing. You need to have the other testers on board as well, and it’s likely that at least one developer on your team will think it’s a good idea and support you. Find a friendly face and ask, “Would you please pair with me today?” Daily stand-up meetings might be a good place to ask as you are all planning your day.
Set a Pairing Session Goal and Choose Techniques to Get There
You’re pairing with a developer for all or part of today, what’s your goal? If you’re pairing to do exploratory testing of a delivered feature, choose the techniques you want to use. For example, you might want to write charters to guide your exploring, or you may choose to use a technique such as a landmark tour. You can have fun with this and your pair will enjoy learning some ET (exploratory testing) skills.
If you and your developer teammate are working on feature stories, bug fixes or chores from your team’s backlog, you can follow their normal development process, and perhaps expand it with testing activities. If you’re doing test-driven development at the unit level, you can help make the tests reflect your shared understanding of feature behavior, and contribute additional test cases where needed. Using customer-facing tests to guide development, as with behavior-driven or acceptance test-driven development, you can use your strengths of knowing good tests to specify, while the developer applies her skill to designing the test code for maintainability. You can also take the opportunity to do some manual exploring before you decide the story is finished or ready for whatever your team’s next workflow step might be.
There are several different pair programming techniques to try out. Ping-pong pairing is popular: Person A writes a test, Person B writes the code to make that test pass, then writes another test, Person A makes that test pass, and so on.
I’ve found strong-style pairing, where you switch roles between driver and navigator, most effective. I’m not capable of writing my team’s production code myself, but I can follow instructions and type when I’m the driver. When it’s my turn to be navigator, I have ideas for tests and for what code to write.
Strong-style pairing works great for exploratory testing, too. The navigator, who’s providing the ideas, has the freedom to observe what happens without having to think about the keyboard. As my fellow tester says, it’s like “riding shotgun” while someone else drives, you get to study the scenery.
Using Pseudocode For Tests
When writing code, one technique that works well, is to first write the test and/or code in pseudocode. That way you don’t have to know all the syntax or be familiar with the code libraries and architecture. Then your developer pair can guide writing the actual code to replace the pseudocode.
In my experience, one key to successful and frequent delivery of valuable new features is achieving shared understanding among the product people, developers and testers of each new feature and story. Using a technique, such as example mapping, for productive conversations during planning meetings helps everyone be on the same page.
Pairing across roles builds on this shared understanding of the story you’re coding and/or testing, and helps you provide the desired value for customers and end users. As a tester, you are likely to take more of a big picture view, see how the story relates to the rest of the system, and think about how customers will use the feature. Your coder pair is probably focused on the area of the code where you are working and how it can be made more robust. These diverse viewpoints help create a better feature.
If you disagree on the desired code behaviour, grab a product owner (PO), designer or other customer proxy and talk about the business rules and examples of desired and undesired behavior. This saves a lot of time when compared with delivering a story and having it rejected because it wasn’t what the customers wanted.
Be A QA - Question Asker!
I’ve found that asking questions is one of the best ways that I can add value. Most developers are more than happy to explain. Walking me through a section of test or production code forces my pair to think through what they’ve done. I often hear “oh wait! It would be better to…” in mid-explanation. I especially appreciate when they grab some paper and start drawing pictures for me.
I do have programming experience, and when I see things that raise red flags for me. I ask about them. For example, if I see a test with a double negative such as:
Example of double negative code
I’ll ask, “I don’t like double negatives. What exactly is this test saying? Can we rephrase it?” Much of the time that kind of question leads to an improvement. Even if you aren’t well versed in good coding design patterns, or in “code smells” that may indicate deeper design anti-patterns, if you don’t understand your pair’s explanation of why they’re writing a test or some code a particular way, ask them to explain.
When I ask questions as I pair, it helps me learn a lot about our product’s architecture, coding standards, libraries and frameworks used, and potentially risky areas. Don’t be afraid to ask questions. Answering them will help your pair, too.
More Ways To Add Value
Technology-facing tests used in TDD or BDD (behaviour-driven development) at the unit level tend to cover the happy path, and that may be good enough at this level. If a sad or negative test case is appropriate, suggest it. Tests at this level are much cheaper to run than UI tests. Hopefully, you already have a happy path customer or business-facing story test that you can automate. Once that is passing, you can move into more story tests for desired and undesired behavior until the production and test code for the story are complete. This is an area where your testing skills can really shine.
As you pair, you’ll sniff out risky areas of your team’s application. Ask your pair what he or she thinks are the fragile or risky areas. Before marking your story finished, do some exploratory testing at the story level to build more confidence about mitigating these risks. This can take the place of the “Show Me” or “Desk Checking” activity.
My current team is also finding good results with a short testing checklist for developer pairs to follow as they wrap up a story. It might contain items such as:
Check in at least two browsers - check for JS errors in console.
(list various locations in your app that might be related).
Verify performance compared to the master branch.
Ensure that we don’t hit the network unnecessarily for resources.
Pairing is tiring! Be sure to take breaks. Using a time management tool such as Pomodoros is one way to stay focused for a set period of time, say 25 minutes, and then take a break for, say, 5 minutes. The few minutes it takes for automated tests to run locally before you commit is also a good time to rest and relax.
Relationship Building Builds Trust
Break time gives you an opportunity to build relationships. My pair and I might discuss a testing framework or technique one of us has heard about. We might grab another pair and play some pong. We might watch kitten videos. After I’ve paired with a developer, I feel more comfortable engaging them in conversation at other times. We build the trust that allows us to have productive discussions. We can brainstorm ideas together without fear. They feel more comfortable to give me feedback and discuss testing and quality issues during retros so that we can improve.
Wrapping Up Your Pairing Session
Talk with your pair at the end of your session and make notes of the outcome. Perhaps you caught some issues that a developer-developer pair might have missed. When I pair, we often find that something missing from the story, and we have to talk with the PO to get consensus on all the desired behavior. Discuss how each of you felt about the session.
What did you like about this pairing session?
What wasn’t so great?
How could we improve it next time?
Should we do this more often?
If it doesn’t seem so great, what other experiments could we try to work towards our goal?
Share this information with your team at your weekly retrospective. As a team, you can decide if the pairing effort is valuable or if you need to make some changes or abandon it.
In my team’s case, everyone has been so positive about the benefits of tester-dev pairing that we now do it more frequently. Instead of one day a week, I often get to pair with a developer two or three days per week.
I don’t have solid metrics to prove the success of our tester-dev pairing. Our main goal was to help prevent showstopper bugs found on release day, or in production after release. We have fewer, but have found it hard to get exact data.
Still, when I pair with a developer, we find lots of issues and fix them as we go before finishing the story, so I’m convinced that pairing helps. Even when not pairing with a tester, the developers on my pod now use their testing checklist and do some manual exploratory testing, and add their testing notes to the story. That saves time for the product owner when she does her own story acceptance testing. We’re making progress on the goal of improving developers’ exploratory testing skills.
Pairing Saves Testing Time
We testers spend much less time in pre-release testing, so we have more time to devote to exploratory testing at the feature level. Yes, some issues still get caught at the last minute, and occasionally even make it into production. However, we’ve been able to deploy to production twice weekly on a regular basis. The deploy might get pushed out one day, but not a week or two as occasionally happened, previously.
While I can’t say this is all down to tester-developer pairing, I think the pairing has had ripple effects that contribute. Developers are more likely to think of better test cases to automate and do some exploring even when they’re pairing with another coder. This frees up testers even more for exploring at the feature level. We feel more confident about our product. Continuous delivery seems within the realm of possibility. And I, for one, am enjoying myself. Finding joy in our work should be our top priority!
I hope you’ll try pairing with a developer and see how many ways it can benefit you and your team.
Lisa Crispin is the co-author, with Janet Gregory, of More Agile Testing: Learning Journeys for the Whole Team (2014), Agile Testing: A Practical Guide for Testers and Agile Teams (2009), the LiveLessons Agile Testing Essentials video course, and “The Whole Team Approach to Agile Testing” 3-day training course. She co-authored Extreme Testing (2002) with Tip House. She is a contributor to Experiences of Test Automation by Dorothy Graham and Mark Fewster (Addison-Wesley, 2011), Beautiful Testing (O’Reilly, 2009) and other books. Lisa was voted by her peers as the Most Influential Agile Testing Professional Person at Agile Testing Days in 2012. She enjoys helping people find ways to build more quality into their software products, as well as hands-on testing. Please visit www.lisacrispin.com and www.agiletester.ca for more.