Pair Programming – A Comprehensive Guide To Get You Going

As of 2016, I have worked in an scrum based agile environment for over five years for a Fortune 100 company. This comprehensive guide was created as a part of mentoring new resources or new scrum teams to make them aware of pair programming and analyze the benefits and techniques so as to meaningfully use the concept and not just do pairing for pairing sake. Here is a summary of what you can expect to learn from this article.

  1. What is wikipedia definition of Pair Programming?
  2. What are the benefits of pair programming?
  3. What negative things people think about pair programming?
  4. What problems may arise in a pair programming environment?
  5. What are some of the good practices of pair programming?
  6. What are some of the popular pairing models?
  7. What are some of the situation to pair on?
  8. What are some of the situations where pair programming might not be beneficial?
  9. How to detect pairing smells?
  10. What are some popular pairing techniques (compare with pairing models)?
  11. When it is not a true pairing?
  12. How my current team pairs?
  13. Miscellaneous thoughts and suggestions around pair programming

Definition of Pair Programming:

According to Wikipedia,

  1. Pair programming is an agile software development technique in which two programmers work together at one workstation.
  2. One, the driver, writes code while the other, the observer, pointer or navigator, reviews each line of code as it is typed in.
  3. The two programmers switch roles frequently

What are the benefits of Pair Programming?

  • More time spent upfront but less defects
    • Less Defects go into production
    • Defects caught early are less expensive
  • Improved Quality of Design and Software
    • Different background of developers
    • Different skill set
    • Different Thoughts
    • Negotiation during conflict
    • Multiple points of view
  • Confidence
  • Team Building and Communication
    • Working as a team towards the same goal
  • Continuous informal review of code
    • Saves you from separate code review
  • More than one person knows what is being implemented
    • Better diffusion of knowledge and transfer of skills
    • New team members get to learn
  • Old team members get to be mentors, coach
  • Continuous feedback and development opportunity
  • More economical
  • Co-ordination between developers is simplified
  • No need to setup extra meetings
  • More focus and engagement
    • Pairs stay focused longer than individuals
    • Less Multitasking
      • You are less likely to multitask when you are a pair
  • Can solve problems faster
  • Fewer blockage
    • One person’s blind spot might not be a problem to the other guy
  • Vacation or emergency situations
    • Less dependence on one person
  • Work ownership
  • Better adherence to organization’s coding standards
  • Better design
  • Share responsibility and pressure
  • Reduced Training Cost

What people also think about pair programming (Myths)?

  • Waste of time and resource:
  • Two people working on one item while they could be working on two separate works
  • Less work will get done
  • Cost will double
  • Not everyone is equal – new and less experienced resources will slow down the experienced ones

These myth’s are either untrue or partially true on a short term. If you look at the larger picture, you will definitely find these myths incorrect.

What problems may arise in a pair programming environment?

  • Conflicts of ideas
  • Conflicts of schedules
  • Partner not available
  • Going over the speed limit
  • False sense of confidence
  • Not ideal in every situations
    • Some research work
    • Both pairs don’t know how to implement
    • Partners hate each other
    • Odd number of developers
    • Work is trivial

Good Practices of pair programming:
The following are some of the good practices to keep your pairing healthy, mutual and productive.

  • Think out loud
  • Switch Pairs
  • Switch Roles
    • Between story cards?
    • Time Sliced?
    • Half hour?
    • Before lunch / after lunch?
    • Between Coding / Unit Testing
  • Be a good listener
  • Get away from your phones
  • Be a good observer
  • Do a team work
  • Communicate well
  • Follow the convention
  • Ask Question
  • Negotiate
  • Accept other people’s ideas if they are better
  • Suggest Re-factoring
  • Everybody owns the code

Pairing Model:

So, how do you pair? Or how are pairs formed? Based on the knowledge and skills of individuals, there are three possible pairing combinations.

  1. Expert and Expert Pairing
    • Highest productivity
    • Greatest results
    • Complex solution
    • Quick Turnaround
  2. Expert and Novice Pairing
    • Ideal
    • Leads to learning and mentoring
    • New solutions and ideas
  3. Novice and Novice Pairing
    • Least Optimal
    • Still better than two new people working alone

What are some of the situations where pairing is helpful?
The following are some of the examples when the pairing is beneficial. Mind that these are only “some of the” example. There could

  • Production defect fix
  • New Story Cards
  • Complex problems
  • Unit Testing
  • Code and Database Design

In what situations pairing is not very useful?

  • Someone asks you to download logs for them
  • A work has trivial or pre-defined solutions:
  • Field name changes on an html component
  • Creating branches from svn
  • Doing builds by pushing a button
  • Research work

What are some of the popular pairing techniques?

  • Ping Pong Pairing
    • Mostly meaningful if you are doing TDD
    • If Brad and George are pairing,
    • Brad writes a new failing test
    • George implements just enough code to pass the test
    • George then writes a test that will fail
    • Brad implements the code needed to pass the test
    • Refactoring is done whenever need arises by whoever is driving.
  • Cross-Functional Pairing
    • E.g. Testers pairing with Developers
    • Or, Testers pairing with Analysts
  • Distributed Pairing
    • Solves problem of geographically distributed pair
    • Developers work via a collaborative real time editor, shared desktop or Cloud Development Environments

How my current team pairs?

  • Pairs are decided at the beginning of Iteration
  • Pairs Take a story card:
    • If a card is 1 or 2 points:
      • Pairing is optional, code review is mandatory
    • If a card is 3 points
      • Person A writes and completes code
      • Person B writes unit Tests in addition to consistently being a navigator
    • If a card is 5 points,
      • Person A writes code until he is tired
      • Person B writes code from where person A left
  • Repeat this until code and tests are complete.
  • If a pair is not found, Tech Key will pair.

When is it not pairing?

  • You identify yourselves as pairs but you sit at two different terminals
  • One person does work, the other one sit behind playing on the phone or with no interaction
  • You split the work and work individually

Pairing Smells:

Not all the pairing might go as expected, or might deteriorate after sometime. These are some of the things to watch for to detect if a pairing has rotten and has start smelling.

  • Pair Marriages – You always prefer to work with same person for a long time
  • Disengagement – worker /rester pairing
  • You agree to whatever the driver does, or the navigator tells you
  • Debates lasting longer than 10 minutes with no new code.
  • Unequal access to keyboard
  • Driver does not explain what he is doing
  • Silence – The pairs are not talking

Other thoughts and suggestions around pair programming:

  • Determine your pair at the beginning of your iteration.
    • Generally done by Scum Master / Iteration Master or Technical Key
  •  Until pairing goes normal, talk about how pairing is going at the daily scrum.
  •  It’s a pain, but it works.
  •  Look for visual indicators such as story cards having only one avatar.
    •  Ideally, every story card should have two avatars.
  • Include pair programming as a part of Definition of Done.
    • If you didn’t pair under normal circumstances, your card is not done.
    • Have a conversation with Tech Key on why you didn’t pair.
  • Get a pair and walk your code with your pair before marking the card as done.
  • If you couldn’t pair for some reason, get your code reviewed
  • Pull an expert from another team if they have time
  • Review does not mean it needs to be done by Tech Key or Tech lead.
  • Pull another developer, or even another pair

Why The Idea Of Test Driven Development (TDD) Royally Upsets Me

(Image Author:Excirial / Taken from Wikipedia / Creative Commons)

I am a professional developer, I write codes day in day out for living. Not only I write my own code, I maintain the code other people write, reviewing it, correcting it, refactoring it, formatting it and making it better as much as possible. I favor writing tests that assure the quality of the work that one has done, especially testing the boundary conditions, making sure the code meets the requirement, making sure the various scenarios are met and the post production surprises are eliminated. I have always found that writing enough tests early and often in the lifecycle of software development not only reduced the amount of UI testing you need to do, but it also gives you opportunity to refactor your code and identify the defects early. Everyone knows defect fixes are cheaper in the early stages of software development lifecycle. Having said that, I am starting this article by making it crystal clear that I am a proponent of Unit Testing and I love writing tests for my code.

Lately, I have been hearing the Test Driven Development (TDD) buzz. I have heard management people talk about it because they heard it on some conferences they went through and would like to implement it in their team and have heard tech leads who mostly spend their time designing  the software but not actually coding it talk about the greatness of this approach. I have heard and seen developers who love talking about it but never write their own unit tests. And I have met those people who are developers, who have used it and are in a love hate relationship with this approach. These things are true either in waterfall model of software development or in the agile paradigm. It does not matter what technology platform you are in – some of these people I have met and talked with work for .NET, Java, Grails, PHP and other technologies.

The idea of TDD – where you write your failing test case, then write your code – sometimes design of such code being driven off the test cases you wrote, and then running the test cases to pass them after writing the actual code, refactoring both the code and the tests needed is great, at least in theory. I can see where this philosophy is leading to – a better code coverage, better met edge conditions, and enforcing the developers to write the unit tests. The idea is great, brilliant, absolutely fantastic – but just in theory.

In reality there are other stuffs such as time constraints, complex enterprise applications, multiple integration points, design-as-you-develop realities, deadlines that you must meet and last but not the least Common Sense. TDD is not a silver bullet in every scenarios.

I feel the same way, this gentleman Chris Maddox feels in his blog:

What boggles my head about TDD is the assumptions it makes. When I begin a project or a new feature, I don’t know what the fuck is going to come out of my head. That blank-canvas-driven creativity leads to novel solutions and unique approaches that keep my code fresh. Many TDD’ers I know would say that if you’re doing TDD correctly, you make 0 assumptions about implementation. I hear that, and it’s total bullshit.

While you’re writing code, deciding what to test and hat is trivial, you make choices. You think about the behavior of the code. At that point, the desired behavior already implies an implementation strategy, whether you care to admit it or not. So by the time you actually get around to writing the code, you are already primed with the complexity of the project at hand.

Here are some of the reasons why it upsets me when I hear too much of TDD preaching at my workplace.

  1. Time Investment:
    As you all know you don’t have infinite hours and infinite days to do your project. You are time constrained. In my team work in a two week iteration and some of these iterations are just prior to code freeze decisions implying if you don’t finish your work by the end of the iteration, it will delay the implementation and then you and your team is suddenly in the spotlight. You are surrounded by the management negativity for not being able to do your work on time. TDD does not help here, TDD does not give me freedom to refactor the code whenever I want it without a fear lying in my back that I will break the test and suddenly I will have to spend a lot of time fixing the test and I am running out of time.
  2. It’s unnatural.
    Nothing in the nature follows TDD. You don’t try to deliver a baby first and make sure you can’t and then you go have sex. You don’t eat a raw flesh of meat, making sure it is uncooked and then cook the food and eat it to make sure it is cooked. You don’t rock climb without a rope and fall and injure yourself intentionally and then do the rock climbing with a rope.
  3. There are no proven statistics:
    So far it’s a theory. There are no proven scientific statistics that tell you that TDD actually makes things better, specially time wise. People have excuses – some say the statistics are difficult because team don’t do the exact same work twice one with TDD and one without TDD. Others say the TDD is fairly new concept and getting industry standard statistics is difficult.
  4. You don’t always create softwares, you maintain it too.
    You are not always writing the softwares from scratch, you sometime (or maybe a lot of time) inherit older systems and you need to maintain those. These maintenance are in the form of some micro bug fixes, smaller enhancements, technical debt reduction, smaller customizations. Now you are modifying a method that’s already 200 lines long, all you need to do is change a few lines here and there. Now your old system may not have existing unit testing. How do you test such methods? Another scenario – you are fixing a bug, you don’t even know what the problem is, how do you start writing tests for things that you have not yet identified where to fix or how to fix? Maybe you start fixing something at one place, then you suddenly realize the problem is somewhere else. Why waste time and effort writing tests first for the things that you don’t even know how you are going to deal with? Defect fixes are more analytical. They don’t have requirements on how to fix a bug.
  5. TDD is a solution. What’s the problem?
    Those who are proponents of TDD keep preaching that TDD is good for this, TDD is good for that. Okay I hear you.. It’s a good solution to certain problems. For example, it enables people to write smaller methods, it enforces writing unit testing, it makes you think about the requirements, it increases your test coverage, it increases the code quality. I hear that, and I get it. But even without TDD, I write smaller methods, I deliver production codes with proper and valid unit tests, I ensure the requirements are met. I read requirements carefully before I begin working on project or piece of work. That’s my professional guarantee. Now why force TDD solution if I don’t have a problem?
  6. It’s a Stress Driven Development
    One of my colleagues joked while we were deeply in discussions about pros and cons of TDD. She said, it’s not a Test Driven Development. It’s a Stress Driven Development. She is 100% right. TDD makes me stressed all the time because every time I want to refactor my code, I have to be worried about my test cases being broken and the need to refactor those. This is different than the trivial style of unit testing where you finish the unit of your work and only when you are done refactoring, recoding, renaming etc  then you do the testing. Your refactoring does not put you under stress. TDD forces me to be less creative, TDD leaves me less freedom unless I worry too much or I spend a lot of time.
  7. TDD forgets that Legacy Systems exists
    Unfortunately in our eco-system, legacy systems that are not designed for Testing do exist. TDD forgets about those. If the application does not have any unit testing framework support, it’s not possible to apply TDD.
  8. You application is more than just Java or .NET
    Just java or .NET don’t make up your application (I mean to categorize the applications that are easily testable via some testing frameworks). Although TDD definitely is independent of programming language, writing meaningful Tests for languages like XML or JavaScript or XSLT might be difficult or impossible if your team or the application itself doesn’t have tools that allow you to test these components. If you are only going to test some components of your application and leave the rest, it does not guarantee a quality delivery.
  9. I Prefer Highways:
    Another thing you will repeatedly hear in TDD is red-green-refactor which normally refers to the failing the Unit (red), then writing just enough code to pass the Unit Test (green) and then refactoring as needed. When you start with failing unit tests, you get to the red zone, then you write the code and make the test pass – taking you to the green zone. Then you can repeat, refactoring as needed – according to TDD. I compare this to taking local roads with speed limits where you stop on every other traffic lights (red), then wait for the green signal and go. I prefer taking highways. It needs a courage and caution to take the highway. It’s riskier than local roads but it’s more productive, it’s time saving and maybe the developers don’t have the grudge about the stumbles on every other block of the road.
  10. TDD is short sighted:
    TDD just looks into the immediate work because of it’s nature of test-code-test trait. It helps you design and test just enough work for your probably next day of work or maybe just another section in your webpage. But in reality, applications cross over each other and are far complex and probably coupled. You can’t just design smaller things without looking into the big picture to be successful. TDD quite does not let you see if there is a dead end in the front, or if there are bigger impacts to your application because you just design and walk a few steps at a time, without really looking into what’s ahead.

I am a professional developer and have a very open mind to technologies and processes. I have no problem trying different stuffs and fail and learn from the mistakes. I thrive to have proper tests for the code that I produce whether I produce them using TDD or just code and test style. If I have infinite time for any projects, I have no problems using TDD. But because TDD exists there does not mean it is suitable to every one. If I produce effective quality code without defects, meeting complete specifications, and without adding extra tech debt to application, and if I am experienced enough to not make shitty designs, I have no need for TDD. After all TDD is a solution to certain problems that developers have. If I don’t have those problems, I don’t need to take an extra dose of TDD.

References and further readings:

12 Basic Principles That Underlie The Agile Manifesto With Text From Original Manifesto

Here is the simplified 12 points version of Agile Manifesto for Software Development

  1. Customer satisfaction by rapid delivery of useful software
  2. Welcome changing requirements, even late in development
  3. Working software is delivered frequently (weeks rather than months)
  4. Working software is the principal measure of progress
  5. Sustainable development, able to maintain a constant pace
  6. Close, daily co-operation between business people and developers
  7. Face-to-face conversation is the best form of communication (co-location)
  8. Projects are built around motivated individuals, who should be trusted
  9. Continuous attention to technical excellence and good design
  10. Simplicity
  11. Self-organizing teams
  12. Regular adaptation to changing circumstances

(Source: Wikipedia/Creative Commons)

The Original Manifesto Text is listed below.

  1. Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.
  2. Welcome changing requirements, even late in development. Agile processes harness change for the customer’s competitive advantage.
  3. Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale.
  4. Business people and developers must work together daily throughout the project.
  5. Build projects around motivated individuals. Give them the environment and support they need, and trust them to get the job done.
  6. The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.
  7. Working software is the primary measure of progress.
  8. Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely.
  9. Continuous attention to technical excellence and good design enhances agility.
  10. Simplicity–the art of maximizing the amount of work not done–is essential.
  11. The best architectures, requirements, and designs emerge from self-organizing teams.
  12. At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behavior accordingly.