I attended a practice-run of a workshop by Jan Eumann and Phil Quinn at Let’s Test this May. If you’re going to the conference, you should check this workshop out. If you’re not going, you should buy a ticket now and go check this workshop out. It neatly captures many of the dynamics that occur when testers and programmers pair. It gave me the opportunity to reflect on some of the things I’ve learned during my time as a tester embedded in a team of programmers, especially around pairing.
I won’t go into all of the details of this workshop, but for a significant portion of it, participants spend time pairing on a program that requires both fixing and further development. Ostensibly, there should be one programmer and one tester. For the workshop, I got to take on the programmer role. Normally when pairing I’m very much a tester, so this was an eye-opening experience for me, more so than I was expecting. I got to see how things look when I’m doing more driving than observing/questioning. Programmer/Tester pairing is a bit different from 2xProgrammer pairing. In the latter there tends to be a fair amount of taking it in turns to drive and navigate. For a Programmer/Tester pairing, how much drive vs. navigate there is depends on things like how comfortable the tester is writing code and how complex the solution (more complex solutions seems to correlate to the need to spend more time thinking deeply about test design and analysing possible failure modes, in my experience). As a programmer paired with a tester I saw for the first time how difficult it can be to facilitate the inclusion of a tester. It has given me a new appreciation for the skills of my fellow programmers at eBay. Here are a few of the things I noticed or was reminded of:
Remember to narrate as you code.
What are you thinking? Are you hunting for a file? What’s the test you’re writing now? Why that test? As I was coding, I was often silent. I knew what I was trying to do, but since the code was unfamiliar, I was spending a lot of time hunting. What I discovered was that my partner was feeling a bit useless because he felt he couldn’t contribute. As soon as he told me this, I started describing what I was trying to do and he was immediately able to start pointing me to sections of the code that he had fresh in his mind. One change required we refactor things in four different files. He reminded me of a couple of steps I’d missed on several occasions as well as noting a few typos that I completely missed. When you narrate your thoughts as you’re writing, you clarify what you’re doing not only for your partner, but often for yourself. Where you find you are hesitant, you might need to throw an idea around a bit more. You also give your partner the opportunity to make suggestions and ask questions.
As a tester, be sure to ask questions. It can be hard to ask questions that you think are dumb – especially when starting out. When I first started pairing as a tester, I felt reluctant to speak up because I didn’t want the programmer to feel like I was telling them how to do their job. I also didn’t want them to think I was stupid. I’ve not had any of the programmers I’ve worked with get defensive or treat me like an idiot. In fact, many things that I thought were stupid questions led to a discussion where we decided to use a different strategy than the one the programmer initially chose.
Thinking about solving a problem (programming) and thinking about how it might fail (testing) really are quite different
– even for people who are familiar with doing both. As my good friend Ilari Henrik Aegerter is fond of saying, it’s the difference between a finite solution space, versus an infinite problem space. The meeting of these two ways of thinking is why I think pairing testers and programmers can be so powerful. As I finished bits of functionality, my partner did some further testing and often found things I’d missed. I consider myself a fairly experienced tester and yet I rapidly fell into a pattern of wanting to get something written so that it works and even though I thought I was considering edge cases and use patterns, I was overconfident in my abilities to handle problems.
TDD is more about driving design than it is about testing, but it can help to facilitate a testing mindset. When you’re writing tests to drive your code, you’re also laying out a structure to your thinking. I find that gives you something visual to brainstorm with. Other test ideas naturally seem to crop up. The middle of the coding flow might not be the precise place to write them or follow them up, but you can certainly note them down to come back to them later.
For the workshop, I didn’t use TDD for the changes I made and not doing this made describing what I was doing more difficult. I think if I’d tried writing a test (check) first, then it would have been a lot simpler for my testing partner to know exactly what I was trying to achieve and to offer input and do further testing. If I’d written tests up front, I might have noticed other things that needed to be tested as well.
One of the things we did do was to talk about what to do next. It put me in mind of something else I see effective pairs doing.
Spend a little bit of time up-front to define success.
Discuss what you want to achieve before you dive into the code. Are you refactoring existing code? What do you want to achieve by refactoring? Are you exploring, looking for bugs to fix? Maybe a charter for specific kinds of issue will help you decide on what to fix now and what to note down for later. Maybe you’re writing new code. What do you want to get done by the end of the session? Do you have all the resources you need? Any mocks or stubs that you need to build? Any integrations you need to do? Is the task defined well enough to make progress?
Effective, productive pairing takes practice. If you know your own role in a pair, you can be effective. If you have experience from both sides of the pair, then I think that has the potential for a very powerful partnership. I work closely with brilliant programmers every day. I see my role as a tester often as facilitating a testing mindset in my programmer peers. It wasn’t until I actually had to step into the shoes of one that I realised that there’s a lot of facilitation on the programmer’s part as well to make sure that a tester has a detail-rich environment in which to work.
I found this workshop a humbling experience. I want to thank Jan and Phil for the opportunity.