Software inspections are traditionally described as a review technique intended to eliminate defects, but in reality they don't work. At least, they don't work now for the kind of projects most software teams work on.
This leaves us with two options: Radically change the code review process or change goals and expectations from defect removal to something more effective. Ultimately, both options may be part of the answer—that is, considering a pair programming approach and adopting a more flexible testing process.
A Start: Radically Changing the Inspection Process
A literature review suggests that the earlier a bug is discovered, the cheaper it is to fix. If that is true, then we should not be inspecting the code after it is complete, but, instead, should perform the review during the programming cycle, in the moment.
This kind of cranking the dial to 11 on peer review has a name—pair programming. A core practice of extreme programming, which was introduced in 1999 by Kent Beck and Ward Cunningham, pair programming is now considered a standard Agile practice, although perhaps not a standard software practice. The classic objection to pair programming is cost, as having two people do one job is something some people find questionable. But does pair programming actually cost more?
Academic research doesn't support that objection, in the sense that projects done with pair programming do not cost twice as much. In 2000, Laurie Williams, a professor of computer science at the University of Utah, co-authored a paper with Alistair Cockburn evaluating the cost/benefit ratio of pair programming. Williams and Cockburn used pair programming in classes. On the first assignment, total time spent by the pair was roughly twice that of one person. The big win, however, was on the second and subsequent assignments, when the total time dropped to about 20 percent more than having an individual do the assignment, even while counting two people on one computer for one hour as two hours.
Beyond the obvious benefits in decreased linear time, or time to market, and modest cost increases, Williams and Cockburn found the code produced was generally more correct and passed up to 15 percent more test cases when compared to code programmed by an individual. (Think of a "test case" as the kind of test a professor would run on the code to determine a grade.)
The final benefit of the case study was fewer lines of code, or more compact code. This makes code easier to change in the future.
Between increased speed and quality and reduced code bloat, it seems reasonable to conclude that students working in pairs were learning. In a different study, Williams found that students who pair programmed were more likely to remain as computer science majors, to become CS majors or pick up a CS minor after taking a course than those introduced to solo programming.
Mary Poppendeick, co-author of three books on lean software development, uses a slightly different approach. She recommends pairing an expert performer with a new performer; this serves as cost-effective, on-the-job training. Poppendeick cites the effective use of this approach in different industries—and for that matter, Dr. Williams is also quick to cite the use of lab partners in the physical sciences in her work.
The "How" of Pair Programming: Two Core Methods
Of the many ways to do pair programming, two core methods have evolved. The first is to have a driver/navigator combination. Here one person has his or her hands on the keyboard, thinking tactically about the current statement, while the observer takes a higher-order view of the code and the changes to the design over time.
The ping-pong approach to pair programming is slightly more detailed than the driver/navigator pattern. With ping-pong, one partner writes a test, and the other person takes the keyboard and implements just enough code to pass that test. Companies that use this method often have two keyboards, two mice, and two identical monitors connected to one actual computer. A variation on ping-pong is to have one partner create the test and make it pass, thus making the roles switch less often.
Most people agree that pairing for more than a few weeks at a time leads to isolation; Tim Ottinger and Jeff Langr list "Pair Marriages" in their set of pair programming smells, or processes to be avoided. While there is broad agreement that pairs should rotate, there is less agreement on how often. Recommendations range from every iteration and assignment, as practiced by Menlo Innovations, to "promiscuous pair" switches every 45 minutes, which Arlo Belshee first suggested in a paper for the Agile Development Conference in 2005.
Improving Traditional Approaches to Code Inspections
Like any process, pair programming has its tradeoffs. Testers are just one of many types of workers who may benefit from inspections, yet they may not be able, or willing, to participate in pair programming. Likewise, pair programming is a social process, which some find distasteful. Chris McMahon, a QA lead at the Wikipedia Foundation, says that, in some cases, an organization may accept third party contributions, or contract or outsource work, and still want to do some form of inspection or audit before adding the code to the build. McMahon add that, while there have been great improvements in screen-sharing tools over the years, some distributed teams continue to find remote pair programming impractical.
James Wang, vice president of peer review products for SmartBear Software, agrees that traditional inspections—done days or weeks after the code is complete—can be a drag on the project. His advice: If you do traditional inspections, make them light, easy and quick.
"The process should be as easy as finding a changeset (or a few) and clicking a button to request a review. This should send a notification to qualified reviewers who can see one set of differences, mark up the differences with notes and send it back," Wang says, adding that collecting audit material should also happen with the click of a button. "If you don't have things like that in place, it will be very hard for your review process to be successful." Wang also notes that chat and IM tools that tie notes to lines of code can make communication easier for distributed teams.
According to Wang, the most effective code inspections involve a small number of reviewers—as few as one—and a small number of changes. A "massive number of code changes" will just "overwhelm people," he says. So does the notion that management is using code inspection as a performance measurement. "If you do that, people will clamp up and stop participating, or just give each other thumbs-up reviews," Wang says.
A Balanced View of Pair Programming
Charles Hooks, a software developer with Press Ganey Associates, suggests that there are several possible goals for inspections—and pair programming may not be able to fulfill all of them. While programmers on his team do 100 percent pair programming (with occasional exceptions for, say, sick days), they also have a separate review step involving a tester as well as a programmer who was not part of the original pair.
"We want to ensure code readability, which can get lost when a pair is deep in the problem itself," Hooks says. "To mitigate that risk, our team involves testers as full participants in the code review process that occurs immediately after the story is complete."
While testers may lack the technical expertise to "recommend some complex transformation," Hooks says that's precisely the point. "The software should speak in the language of the problem, not in squiggles and clever hacks. If the testers can't understand it, it needs to be more clear."
Putting It All Together
Research and interviews conducted for this article lead to one consistent, best answer for code review: continuous pair programming.
While your organization can get some benefit from reviews and may want to use them in addition to pair programming to mitigate different risks, pair programming wins hands down.
Allow me to leave you with some advice. Your organization may have serious functional, cultural and technological objections to pair programming. I understand that.
However, the benefits will outweigh the up-front costs as well as the learning curve associated with pair programming.
Do it anyway.
Matthew Heusser is a consulting software tester and self-described software process naturalist, who develops, tests and manages software projects. Matt is a contributing editor for Software Test & Quality Assurance Magazine and his blog "Creative Chaos" focuses on software writing. An elected member of the Board of Directors of the Association for Software Testing, Matt recently served as lead editor for "How to Reduce the Cost of Software Testing" (Taylor and Francis, 2011). You can follow Matt on Twitter @mheusser or email him.