New article at Ranorex, “Why You Need at Least Three Sets of Eyes on Your Code”

three sets of eyesWhy You Need at Least Three Sets of Eyes on Your Code (9-Jul-2018)

Passive review after code (PRAC) is largely a waste of time.

In this blog post for Ranorex, I provide some reasons why active review is better than PRAC. I discuss pairing and mobbings as two forms of active rule, and present a core rule for review that focuses on outcome instead of mechanism.

New article at Gurock, “Balancing Mobbing, Pairing and Solo Work”

mobbing, pairing, soloBalancing Mobbing, Pairing, and Solo Work (21-Jun-2018)

(Well, I like the Oxford comma, even though my editors do not.)

I view modes of working as akin to tools–you want to use the right tool for the right job or situation. In this blog post for Gurock, I talk about the distinctions around appropriateness for mob programming and pair programming. I also admit to enjoying the ability to work alone from time to time.

Where Are the *Real* Agile Tools?

There are at least a hundred for-profit or open source tools to help you track your agile / Scrum project. Here is a list, from 2013, of 70 such tools.

tools “tools,” courtesy Andy / Andrew Fogg. License.

If you’ve read Agile in a Flash or some of my blog entries, you’d quickly gather that I’m not a fan of most software-based project tracking tools–you’re better off using whiteboards and/or physical card walls. Introduce a software tool only if you must. And if your need is solely for reporting up to management (hmmm), remember that it’s the SM’s/project manager’s job to capture, consolidate, and distribute such information. Please don’t involve the rest of the team in this.

The tools I seek instead are those that help our team communicate and collaborate better. We’re 15+ years into “agile;” I’d hoped for far more collaboration tools than exist today. (What’s my excuse for not building any of it?)

Development Tools

IDEA, Eclipse, and even VisualStudio (with Resharper added) are powerful. To what extent do these tools directly support TDD? IDEA, Eclipse, and VS all support unit testing out of the box, but that scratches only the surface. While plugins exist for many of these interests, I’d like to see direct support for things like:

  • find usages in tests only
  • switch between test and production class at a keystroke (or even… open the test, it opens the prod file, and vice versa, and aligns them in split windows)
  • provide the ability to configure formatting in a different manner than production code
  • built-in coverage tools

With TDD, tests and production code are inexorably linked. It would be nice to work in an IDE that supported TDD as the primary workflow for building software.


Pairing will never supplant loner development. But it’s still a preferred way of working for many developers, including those distributed geographically.

Shared Machine

If we’re pairing and you’re sharing your machine and IDE, I’m stuck with your horrifying choices for keymaps (I need my vim!), colors, font, and font size. One or both of us must make concessions to the most-comfortable setup we would choose. How sad.

The problem of disconcerting configs would be reasonably easily solved if the major IDEs supported a universal config-switching scheme. Sets of profiles (one profile per IDE, I suppose) would be stored somewhere accessible via http. The first time I sit on your machine, I’d enter my profile-set location. The IDE would provide a universal hotkey that toggles between active profiles (right now, you would typically need to go through one or more Preferences/Settings pages to switch out all the preferences). My turn to pair? I press the toggle hotkey, and my preferred setup is loaded..

Another focus would include supporting accessibility considerations for pairs. Some folks need a considerably large font, for example. A pair-friendly IDE would provide the ability to easily sport multiple views across multiple monitors.

Multiple Machines

Using multiple machines might ultimately be a better world than my shared machine ideas above, even if I’m physically sitting next to you.

Screen-shared programming sessions usually suffer latency issues, particularly for the remote pair. If you’re a VIM or Emacs weenie, however, you can run an effective pairing session using tmux/tmate or screen. The character-mode interaction makes it almost as good as being there–particularly when coupled with cameras, quality audio, and a screen share so that you can see the UI interactions on the host machine. This is my preferred remote-pairing setup, but I admit that there are some great things I lose that IDEs like IDEA can provide.

Atom also supports a plugin called Motepair that “enables remote pair programming using Github’s editor.”

Subscription-based cloud IDEs like Cloud9, Codeanywhere (which has a free version), and Codenvy are an option, but for now, most of us would probably prefer to stick with our IDEA or VisualStudio or Eclipse. (And I’m resisting paying for yet another subscription…) Having not used these, I’m not sure how truly collaborative they are. Your experiences are welcome in the comments!

The subscription-based Floobits takes things one step further, offering the premise of allowing clients to use whatever IDE they choose… as long as it’s Emacs, IDEA, Neovim, Sublime Text, or Atom (no Eclipse or Visual Studio yet). I’ve not tried it, but it sounds fantastic. Koding appears to be another tool with a similar model.

Other attempts have been made to create remote pairing plugins for specific IDEs. I remember XPairtise, an Eclipse plugin, which was file-based (it synced at the file system level) and had no end of problems. Now there’s SAROS, a still-active open source initiative.

In-Meeting Tools

There’s little worse than watching someone struggle through typing story data into a tool like Rally. The tool often requires lots of clicking about, which can create a distraction for the rest of the team in the room.

In contrast, I’ve found simple virtual card wall solutions like Trello to be fantastic, however. I’ve run and been a party to iteration planning, retrospectives, and other distributed (and non-distributed!) meetings where Trello was the tool of choice. It’s highly tactile and responsive; all parties see changes as they occur. With plugins, things like dot-voting on cards promote Trello to a great general purpose tool for managing and tracking just about any collaborative meeting. Worst case is that you need to export the information to sync up another tool elsewhere.

Ultimately: I wish all applications supported true real-time collaboration. Google Docs is a great example of a tool that effectively supports live editing by multiple people.

If we really believe in agile, let’s insist that the tools we use and build all support collaborative capabilities, and not just as an afterthought.

Pairing Hell

pair hell
Image courtesy Chris Martin; altered from original. License.

“Pairing is hell. Okay, it’s also fun. But it’s also hell.” —Alex Harms, on pair programming.
Over fifteen years of pairing, and I too am similarly ambivalent about it. Don’t think I’m making a case for not pairing, however. I’ve written numerous times in support of pairing:

At least 16 more blog entries on this site discuss pairing, as do many at the Agile in a Flash blog.

So “hell,” really? Seems strong. Let me explain what I find to be a few serious problems with pairing cultures that can make it hell.


As an introvert, I have a limit on the number of hours I can interact with people before I need to recharge (i.e. on my own). I regularly stretch this amount, which is ok. It doesn’t mean I’m not enjoying the interaction–particularly if it’s going well. It is heavily draining, however, which demands more recharging.

Pair programming was never meant to be the only thing you do all day. And yet I’ve done regular stints of 9-10 hour pairing days (at HEB in San Antonio for 7 months), or 7-8 hour days (remote at Outpace for the past few years). Trust me, those aren’t 100% fun hours for an introvert, no matter how well it’s going.

Sensible pairing shops set a limit on pairing. Six hours is plenty: three hours in the morning, three in the afternoon, a break in each. One shop I’ve helped mandates such a schedule to positive effect–no one feels pressured to stretch beyond reasonable amounts.


Some people either never learned to play well with others or are incapable of it (i.e. it’s not their fault). Still, I believe most individuals are capable of learning how to interact effectively as a pair.

Having said that… there are definitely a (very small) number of pair-holes: people who should just not pair. Ever. Again. And I hope to never have to pair with these folks again. Fortunately for them and me, plenty of shops don’t mandate pairing, and shops that pair usually have other non-pairing things to do.

What makes a pair-hole? Mostly it’s someone who’s “always right,” or worse, someone who wants to argue (and not code) just for the sake of arguing. A keyboard dominator can sometimes be a pair-hole.

Many bad pair habits (inattentiveness, timidness, loud, etc.) can be corrected or overcome. A pair-hole is someone who doesn’t care enough to do so.

I’m not talking about people who want to think through problems on their own instead of with a pair. I think just about everyone feels that way some of the time, including me. I find that exploring things on my own is necessary as a regular thing. I find time regularly to do so–that’s one reason I seek slightly less than a full day’s pairing.

Poor Practice

Other than pairing too long, I’m mostly talking about pair marriages. We promote pair switching to increase coverage on everything. A pair can go down a rathole, just like a solo dev can. I suggest all shops incorporate a rule that says “at least 3 sets of eyes review every story,” whether through pairing or some other mechanism.

That’s the practical concern regarding pair marriage. The painful part: Being stuck with the same person day after day–or even all day long–can be a big pairing turn-off, like long walks down the beach can be (because you know you have to walk back). Switching at lunchtime can work well.

Pairing is a Tool

Pairing can be a highly entertaining, effective tool. For me, it’s often joyful. But it can at times be painful. The more you understand the extreme feelings and concerns people have with respect to pairing, the more you’ll learn how and when to effectively employ the tool.

If you’re not actively coaching your pairing and not continually adjusting your pairing practice (perhaps as a result of retrospectives), chances are good that you have the above dysfunctions.

TDD: No Fun, No Gain?

Party DogIn “TDD Is Not a Silver Bullet” I reproduced part of an interview with Tim, a sharp young corporate developer that I’d paired with very briefly in 2006. In 2008, he sent me an email about his experiences in the interim. Tim’s stories are what prompted me to want an interview with him. Here’s a portion of the email.

Much to my surprise, it is being conveyed from the head of our development that we need to be “stressing” TDD.  My surprise was… I thought we already were practicing TDD on an enterprise level.  Regardless, I guess they had brought in this guy named [Very Big Agile Name deleted].  (I am sure he runs in your circles.) If you are friends with him, take what I am about to say not as an insult, rather my perception; but if he would have been the expert to introduce me to TDD, I would never even thought of adopting/agreeing with it.  And, as it turns out, the teams he consulted felt the same way.

I have been telling my boss about my experiences with you, and told her it would be like night and day.  I respected the fact, that while TDD was the stressed point with you, you also provided more than just using TDD as a silver bullet per se.  Basic things… like knowing the language, having fun, communicating, and so on.

I got in touch with Tim this week to make sure he was ok with me publishing this stuff four years later. No surprise, Tim is still doing (and presumably enjoying) TDD.

If you’re a “real” programmer, you find coding fun at least some of the time. Of course, it might not necessarily be fun when the code fights you all the way, hiding bugs and throwing nasty dependencies in your path. Still, I happen to enjoy coding always, despite the challenges. Test-driving is fun, too–it’s more code, and it gives me confidence to craft cleaner code, which is even more fun.

Maybe learning doesn’t have to be fun to be effective, but I have to figure sucking the fun out of it on purpose can’t possibly work. (I’m disappointed that a Very Big Agile Guru could do that.) Yes, the sticky challenges of real code mean that you can’t teach TDD with a few trivial, “non-real-world” examples. That’s why I employ a deliberately horked-up, fairly realistic codebase in my training. But the class also learns that it’s only a challenge, not a barrier, and they quickly learn a few simple techniques to surmount the challenge. They have a good time learning TDD.

Ultimately, my students leave the classroom enthusiastic about the prospects for TDD, and confident that they at least have the basic understanding needed to begin tackling their challenges. After that, it’s a matter of their having good support for the practice. (Being the minority in a team, as I’ll relate in a later blog post through Tim’s stories, is a great way to lose that enthusiasm.) When I get to pair with developers to help them through learning TDD, both of us have a good time.

If you’re interested in coming up to speed on TDD, make sure you pick trainers and consultants who don’t suck the fun out of it.

Code Socialization

The first rule of Fouled-up-code* Club is you don’t talk about the code.
The second rule of …

We don’t talk about the code, and so most of us are members of F’d-up-code Club. We’re not socializing the code enough. Shop upon shop I visit, I ask when the programmers discuss what’s in the code with each other. The usual answer?  “Once in a while.”

If you’re not regularly talking about the code as a team, it’s getting worse. And “it” includes the time to understand the code, the time to fix the code, the pain the code causes you, the defect count, and ultimately the extent to which you have a real team.

We create standards but they idle and adherence falls off, and the code shows it, and attempts to get back on track fall short. We pair-program, but don’t switch pairs mid-story, and the solutions show it. (Yes, two heads produce a better-than-one solution, but a pair deep into understanding of their feature can easily produce a solution that makes little sense to others.) We hold tepid brown-bags that bore attendees and ultimately taper off in quantity. We hold retrospectives, sometimes, but the process crud dominates, and the audience isn’t usually right for talking about code problems. We sit in the same area (well, a small number of us do), but rarely call others over to our monitor to look at some cool or challenging code.

Try this (the opposite of the prior paragraph, duh):

  • Revisit your standard once a quarter at least, or simply when someone wants to visit a specific standard issue.
  • Pair program and take advantage of the two-heads effect. If you can’t pair, incorporate a streamlined inspection process. If you can pair, switch pairs at least once mid-feature. See if the third party can make sense of your tests and solution with minimal assistance from you.
  • Run end-of-day code sharing sessions on the LCD projector. Limit them to 15 minutes, and shoot for 5 minutes. “Hey, can we stop doing this in the code?” Or, “Here’s a new reusable construct that we should all be using.” Or, “Here’s an effective tool tip I learned.”
  • Find 60 minutes for a programmer-only retrospective each iteration. Make sure what comes out of them are commitments to improve that are actually met (otherwise don’t bother).
  • Don’t wait for the end of the day or a pair switch to discuss something important in the code. People should feel comfortable about standing up and finding an audience for a 5-minute ad hoc code discussion.

* More blunt folks can substitute other words for “fouled.”

Collaborative (Dare I Say Pair?) Writing

I enjoy writing, though I’m not as prolific as I’d like to be. I tend to re-read what I wrote many times, often second-guessing it. Like any writer, I also find difficulty from time-to-time, getting stuck on how to phrase a paragraph or a sentence. I’ll typically mark things and return to them later. All-in-all, I can slam out text, but getting polished product out the door can be challenging.

ball point pen writing

I read and enjoyed Weinberg on Writing: The Fieldstone Method when it came out. I already had been employing its core idea to an extent: capture thoughts as they arise (index cards work great!), then incorporate them as appropriate in an article or book. Each idea on a card might act as a central idea around which writing can build, or it might be used to fill in a “hole” in the text. Emphasizing this technique has made writing a lot more fun, and I tend to not lose great thoughts that had popped into my head.

My best writing experience, however, has been collaborating online with Tim Ottinger, originator and co-author on Agile in a Flash. We had a slow winter–after writing a pile of articles for PragPub, we both got very busy with work, and did little writing. We finally found some time to commit to delivering a new Agile in a Flash post, Is Your Unit Test Isolated?

Two days ago, we got our headsets on, started up a Skype conversation, and talked for a few minutes to agree on what we’d work on. We started some single-threaded editing on a very rough draft at Blogspot, but that wasn’t effective, so I pasted it all into a Google Doc.

Google Docs doesn’t provide the best document editor in the world, but it is highly effective for collaborative writing. You can see each others’ cursor and typing as it occurs, and you can look at offline revisions if necessary for comparison.

Mostly we’re not talking via Skype (and in fact sometimes we’ll collaboratively edit without a voice conversation at all). Instead we’re communicating through the document. Tim will start re-working a paragraph that I might have just finished writing, and I’ll get out of the way. Sometimes I’ll watch and toss in a comment–just typing it right into the document–and other times I’ll go off and stab at a paragraph that Tim wrote. Or I might go off and re-read the document, looking for flow and completeness problems. It’s pretty haphazard, yet it works, and it’s fast. We might go back and forth at a paragraph a few times before we figure it works.

Collaborative writing works best if you grow a layer or two of skin. We’ve learned to be pretty direct: “[[ I don’t like that ]],” Tim might type (the brackets are our way of setting off comments). Ok! Good technical writing requires harsh critique. Better Tim drop a pointed comment than a few thousand readers.

At times I’ll return to find something I’ve written completely gone or gutted and rewritten. It was a little disconcerting at first, but I’ve learned to trust Tim’s reworkings. I can always look at the old revision if I thought an important idea got deleted.

The unit test article took us about an hour to get to 98%. We let a couple outstanding concerns sit for a few hours, made some offline changes, and published it the following morning (yesterday).

As with pair programming, I’ve found such highly collaborative pair-writing to go much faster than writing on my own, and produce a far more effective product.

Don’t Stop Reading…

When writing, be careful of presenting an opposing point first with the notion that you’ll make your counterpoint in a subsequent paragraph or page. That first pitch is often as far as some readers get. Royce’s article “Managing the Development of Large Software Systems” led to decades of waterfall for this reason.

Recently, a pair-developer expressed concern over the use of multiple returns in a short method. I said I knew about the long-standing rule but that it created little value for very short methods. Two days later, I heard the same concern during another pairing session. Twice in one week? Curious!

I asked where they’d read about the rule. “Uncle Bob’s Clean Code” was the surprising response. “Hand me your copy!” I insisted, a bit worried, and quickly located the text in the functions chapter. The very last paragraph on page 48, starting a new section, states: “Dijkstra rules of structured programming… [say] …every function … should have one entry and one exit. Following these rules means that there should only be one return statement in a function…” Oh! Yeah, I learned that 30 years ago. Really, Bob?

Page 49, top paragraph: “”While we are sympathetic to the goals and disciplines of structured programming, these rules serve little benefit when functions are very small. It is only in larger functions that such rules provide significant benefits.”

Oh, ok. Whew! Crisis of faith averted.

Readers: Inattentive reading can be embarrassing!
Writers: Don’t assume readers will get to your point. Make it first.

Not Giving Up on vi(m)

I wrote this blog as a reaction to reading James McKay’s blog entry, “:q!,” in which he describes abandoning vim. A story familiar to me, but I fortunately never abandoned it for good. I do have to agree that Intellisense and other wonders of modern IDEs make them the preferred environment for things like Java, but I still get a lot of use out of vim.

In the past, I’d be forced to use vim while, say, having to do a small amount of my work on Solaris servers, but then I’d be back on Windows shortly thereafter. I loaded RedHat at home many years ago but it didn’t stick. Then I tried Ubuntu… a couple times, and Un*x finally stuck. Yet I was still only occasionally using vim, which meant I was a perpetual newb, at a “level 1” of vim capability (I’ll sadly call the scale the VCM, or vim capability model).

VCM level 1 is the ability to get in and out of the tool and do basic editing (search, page forward, change/replace text, occasional use of the dot operator, etc.). I remember that I too thought the only way to delete many lines was via count-based commands (e.g., 10d). At VCM level 1, vim beeps at you a lot, and you don’t understand why people swear by it.

What changed things was a result of being forced into having to hit vim on a daily basis for an extended period of time. I had the opportunity to work with Tim Ottinger a bit, and we would pair from time to time. Tim is the author of a great article on vim, “Use vim Like a Pro.” I won’t mention pairing after this paragraph, but I will say that without the ability to pair with someone at a higher VCM level, I might never have advanced much from my level 1 proficiency.

I’m making up the VCM based on my history, of course, but it might just work for others, too. VCM level 2 is marked by use of these critical elements of vim:

  • regular use of the dot operator
  • use of hjkl for cursor movement
  • ability to manage buffers, registers, and split windows
  • ability to visually mark code
  • regular use of f and t in combination with other commands; use of other context-based movement commands
  • use of ctrl-n for auto completion
  • awareness and occasional use of macros
  • occasional use of help facility to learn something new
  • regular (no pun intended) use of regex
  • use of ctags to aid code navigation

Reaching level 2 was important: At level 1, I simply thought vim was a frustrating, not-very-powerful tool. At level 2, I am fairly effective when editing, and faster at many tasks than most people in their GUI editors. I also see that there is much more to learn and master.

Tim is probably at VCM level 4: mastery of most, if not all, of vim’s features. I suppose that marks Level 3 as when you have ingrained all the major facilities (i.e. most everything that Tim covers in Use vim Like a Pro), are trying to ingrain something new on a regular basis (I’ve now habituated the use of ~ to toggle case, for example), have considerably customized your .vimrc, and are making an active attempt to do everything in the most efficient way possible. I am getting into level 3 now, but I haven’t used vim heavily in a while.

During my fortunate opportunities to learn vim from Tim, I discovered there were a few things about vim that he didn’t know. Shocker! It’s an extensive tool, but I guess what that means is that there’s a VCM level 5. Let’s define that as mastering VCM Level 4 plus everything that Tim doesn’t know now.

Abandoning Pairing

For almost a year, I pair programmed on a daily basis as part of a team working for GeoLearning, a small software company that is no more. My enjoyment was tempered by the fact that I was pairing remotely, online with a headset and sometimes a camera, using Skype and WebEx. The contrast to live pairing was marked.

Remote Pairing Cons

  • Lag. Whoever was not hosting the session suffered enough lag to make the experience a bit painful. We didn’t switch enough, probably because of the cost of switching overhead (not only the desktop switching itself, but also getting the source across, which really isn’t all that big a deal with git).
  • Noise. Some people breathe rather heavily, others swallow loudly, and some like to chomp on snacks too much. I did mention it from time to time, but it always felt awkward. And either I was a very good pair, not making these sorts of noises–I doubt it–or others similarly didn’t want to speak up.

Pairing or not, as a remote developer I didn’t feel like I was a real part of the larger, “live” team. I felt that my influence as a remote person was insufficient.

The remote pairing also carried the same issues that “live” pairing can create, most of which are minor. For example, the team had very few standards, which led to some wasteful debates during many of the pairing sessions, still not that big a deal. But couple a lack of standards with stubborn people, and you have a useless pairing session.

I can get along with just about everybody; not the case this time out. I paired with one developer whose concept of TDD was almost completely opposite mine. We produced virtually no useful product during our two or three pairing sessions (we then ended up on different teams, thankfully). In attempts to stop the arguments, I would often say, “Let’s just go with your preferred way of doing things for now.” No such luck. Some folks are simply contrarians.

Remote Pairing Pros

  • It allowed me to stay at home, very welcome after many years of travel, which had created a significant negative impact on my family life.
  • Learning a new system without the ability to lean on someone for several hours a day is tremendously wasteful and frustrating. Remote and isolated, it’s even worse. Pairing rapidly brought me up to speed to the point where I was able to contribute.
  • I could work with the remote pair and not be uncomfortable about things like sitting too close, bad breath, or my laziness on some days when I didn’t feel like showering.
  • The slow cycle times (waiting on compiles, test runs, etc.) were almost bearable due to the fact that you had someone to talk to for the minute or two or more.

Being remote sucks in so many ways–primarily the isolation from the rest of the team–that I wouldn’t have even considered the position had it not been for the ability to pair. I never felt like I was a real part of the larger, “live” team, and I felt that as a remote person I was unable to influence the team much.

So despite the negative aspects of my remote pairing experience, it was the best that I could expect for this opportunity. Ultimately, having this opportunity remotely was better than not having it. And the pairing brought me a small but significant step toward feeling like I was a real part of something.

Pairing No More

I’m currently working a three-month contract for a local firm. It’s a very stable company, there’s no travel on the near horizon, and my commute is about seven minutes door-to-door (it’s three miles away, with only one stoplight inbetween). Those three elements are great, but just about every other element–ranging from pay to preferred way of working to technology–is a concession.

There’s no pairing. My first “real” week (i.e. past most of the HR and setup BS) was spent sitting in an office, digging through a (test-less) codebase, occasionally IMing my teammate a couple offices over to ask questions. It’s a typical no-process environment.

Here’s how I feel about no longer pairing:

  • Bored. Cycle times are again high. I miss having someone to discuss things with during the waits. Checking email, tweets, RSS feeds, and Amazon book ranks helps only a little.
  • Lonely. Stuck in my office with no one to talk to and bounce ideas off, I don’t really feel like I’m part of a team, just one of a number of individuals who happen to work on the same code base and project.
  • Conflicted. I second-guess myself continually. “Is this the company way? Is this the [unfamiliar-to-me technology] way? Does it violate standards? Is it the best design? Did I just do something really stupid? Am I going to get chewed out or look bad for checking this code in?” Unfortunately, second-guessing produces far weaker answers than simply asking someone who already knows and can quickly tell me the answers.
  • Released. One downside of pairing most of the time is it tends to suppress learning by exploration. While I don’t want to work that way all of the time, I’ve found I often learn better when I probe about and try things. With a pair, I usually feel the pressure (even if I’m really the one creating that pressure myself) to move on. And many people who already know the answer tend to simply prefer to tell you it, or more typically grab control and do it themselves rather than wait while you muck around.
    While this may sound damning, it’s easily rectified in a pairing environment: Set a time limit to pairing. I’ve found that a six-hour window is plenty, but it’s up to you and your team to figure out how much works well for you.

Pairing is not for everyone or every team. The bullets above suggest that there are serious challenges both with pairing and with not pairing. But most of the time, I’ve found pairing to be far more enjoyable and productive than not.