Being skeptical: Pair Programming

Introduction
The term “pair programming” was originally coined by Kent Beck and refers to a software engineering technique in which, a pair of people sit together on the same desk, side by side, and work on the same task. The process can occur during all development phases, including not only coding but also design, testing, algorithm design, debugging and so on [1](p. 312). The basic setup of pair programming consists of two roles, a driver and a navigator. The driver, is the one who focuses on the task, writes the code or puts down the design. On the other hand, the navigator is responsible for real-time review. Therefore, he or she has to observe the driver and think of strategies for solving any possible defects. The navigator is not as deeply involved as the driver, consequently, he or she can have an objective point of view and think strategically about the direction of the work. As you can imagine, in case the navigator is quite and does not communicate, the pair is considered dysfunctional [1](p. 311). During the pair programming process the driver and the navigator should switch roles. In some cases, it is common for peer rotation to occur among team members.

Benefits and Limitations
Pair programming is considered as a controversial technique for many reasons as it has both benefits and limitations.

Communication
First of all, by applying pair programming the development process, from a solo activity becomes a more social one. This is because, there is constant communication between the participants. The two peers are now “brainstorming partners”. Research suggests [2](p. 51, Pair Programming Chat) that they solve problems a lot faster, and the quality of the work is usually higher because of the ideas flowing.

Additionally, they are “chatting partners” [2](p. 51, Pair Programming Chat). This helps on work effectiveness since the peers are continuously talking, triggering new ideas. In the case where one peer gets stuck, the chatting helps to unstuck them, the same way as when solo programmers talk about their problems out loud. Furthermore, the “pair pressure” [2](p. 53, Fighting Poor Practices) creates the feeling of not wanting to let your partner down. For this reason, a relationship is created between the two partners which sometimes can lead to satisfaction [3](p. 4, Satisfaction). Particularly programmers think that pair programming takes them out of their “comfort zone”, but as research has shown [3](p. 3, Economics) after some time when a relation has been built, programmers en-
joyed pair programming more, and were more confident than when they programmed alone.

Importance of Peer Rotation
As it is already mentioned, communication continuously triggers new ideas to the participants of a pair duo. However, as psychological research shows [2](p. 53, Pair programmers notice more details) when two programmers pair together, the things they notice and fail to notice become more and more similar. Eventually, the benefit from two pairs of eyes becomes negligible. That effect is called, “pair fatigue” and significantly affects the productivity of a pair. As a result, Kent Beck suggests that the pairs should rotate frequently, even twice per day.

Knowledge Sharing
Next, and what I personally consider as the most important aspect, is knowledge sharing. In a big team there is a wide range of expertise between its members. As a result, when putting people to work together, the knowledge is constantly being passed between the participants. This knowledge includes tool usage tips, design, programming insights and overall skills. In addition, since two peers who work together will not have the same prior knowledge, one will spot some insights or defects faster than the other.

Bad Habits
It is a fact that software engineers are used to working alone, especially those who were educated this way. Also, many of them have the idea that by using pair programming they are wasting their time because their peers will slow them down. However, from the psychological field there is what its called “inattentional blindness” [2](p. 52, Pair programmers notice more details). Inattentional blindness suggest that, if we do not know what to look for, we can stare right at it but still miss it, and what we notice depends on what we expect to see. According to that, although some pair programmers will concentrate mostly on identical parts, they might notice different things.

Economics
The most challenging issue of pair programming is the financial one. Although there are many research results [1](p. 314-317) which support the contrary, the software organizations still believe that pair programming will double the development costs, because two programmers are working on one task. As most managers think that by using pair programming they double the code development costs, they reject it’s usage [4](p. 1, intro). Consequently, a solution to that is to inform the management about research and empirical results that show how, why and when pair programming works in order to have a complete overview of the technique before rejecting it. However, from my experience, applying pair programming in a startup setup is a has bad effects in the economics factor, because usually a startup has to “move fast and break things”, owing to that, this kind of companies do not focus so much on the quality of the product that a pair programming process would provide, but more on speed and parallel work. As a result pair programming is not appropriate method to use in such companies structure.

Coordination
Since more that one person needs to work on a single task, they need to coordinate with each other. This is a problem because they have to work at the same time, on the same team and therefore synchronize their schedules. According to research [1](p. 321, Challenges), one way to resolve this issue is to determine the composition of the pair programming duos during the scrum meeting.

Distributed Teams
Finally, pair programming by definition implies that the participants have to be colocated. However, pair programming would also work in a distributed team.

Distributed Pair Programming
There is a whole new branch of pair programming that is called “distributed pair programming”. Apparently, these distributed team participants can work on pairs using a variety of tools that are available on the Internet. According to research [1](p. 319 Distributed pair programming), distributed pair programming has also proved to be beneficial, although not as much as the co-located pair programming. More specifically, in the case of students, they viewed pair programming positively in general, but the distributed pair programming significantly less favorably.

Variations
There are some variations to the pair programming setup depending on the experience and the expertise of the two participants.

Expert-Expert
Of course, the obvious choice for the managers would be to pair two experts in the field in order to achieve the highest productivity results. However, this does not always work since both parties consider themselves experts in the field and it is unlikely to question their practices. Due to that, navigator’s feedback may not provide the wishing insights and the process might be unproductive. In some cases only one person keeps the knowledge of a module in the system and thus the team can suffer if this person leaves. However using the “expert-expert” combination could save the day in such cases by increasing knowledge sharing and make it available to more people in the team.

Expert-Novice
This combination is the most suggested one [2](p. 50) since it brings the maximum benefit in both the team and the product. The knowledge sharing in this case is significant, while experts transfers their knowledge to novices and novices can introduce new ideas, as they are more likely to be more critical about the established practices. On the other hand, an expert is more likely to challenge and inspire the novice. However, in this type of pairing, a novice may be passive and hesitate to participate meaningfully in the process and as a result this will lead to an unsuccessful pair.

Novice-Novice
This pair is usually discouraged [3](p. 6, Problem Solving – Learning) since the knowledge sharing is very low and the communication could be proved difficult because both of the participant will take a passive approach to the process. However, when is used in students it shows significantly better results than two novices working independently.

Empirical study
Pair programming, is a widely used practice with numerous studies in both industry and education. The results are presented extensively in [1](p. 313, A History Of Pair Programming), [3](p. 3, Economics), and [4](p. 3, Factors of the economic comparison model) .

Pair Programming In Industry
The research shows [1](p. 313, A History Of Pair Programming), [3](p. 3, Economics), that in industry the products took 4% more time in case of pair programming, although the quality of the code was a lot higher, with 39% fewer defects in user acceptance testing. Also, pair rotation in industry is a very common practice to maintain the pair dynamic and the knowledge flow.

Pair Programming In Education
Pair programming in education has showed very good results since it creates an environment for students which activates learning, enhances social interaction and boosts confidence. Not only that, but they also feel more responsible of the task and they are afraid of jeopardizing their partner’s grade. Therefore, they are more active and  articipate a lot more than if they were alone. In the educational setting, the pair rotation is very rare since educators prefer pairs to remain consistent for a whole semester because the overhead of communication could be important.

Conclusion
Although, pair programming results to higher product quality, enhances learning and reduces risk due to improved knowledge management, and, finally, enhances team spirit significantly, it is hard to convince the management to implement it. Therefore, the managers have to invest time to research the subject and give it a shot, since as studies suggest the results are very impressive and this technique becomes more and more popular.

References
[1] Oram, A., and Wilson, G., 2010. Making software: What really works, and why we believe it. ” O’Reilly Media, Inc.”.

[2] Wray, S., 2010. “How pair programming really works”. IEEE software, 27(1), p. 50.

[3] Cockburn, A., and Williams, L., 2000. “The costs and benefits of pair programming”. Extreme programming examined, pp. 223–247.

[4] Williams, L., and Erdogmus, H., 2002. “On the economic feasibility of pair programming”. In International Workshop on Economics-Driven Software Engineering Research EDSER, Vol. 4.

Advertisements

Being skeptical: Test Driven Development

Introduction
Test driven development (TDD) is an agile practice that has been introduced by Kent Beck, or as he puts it “rediscovered” in his book “Test Driven Development in Practice” [Kent, 2002]. Its structure is simple although a bit controversial because of the way it affects the development process. TDD is represented by a development circle, starting always with writing tests and then followed by writing the implementation code.

How it works
Indeed, the first thing is to make a list of the tests that you have to write in order to achieve the goal of your software. The idea behind this, is that it makes you think about the requirements and the specifications of the software before you write any code. Next step is to run these tests and get the “red light”, meaning that those tests should fail. This will ensure that the tests really work and validate the test harness. Therefore, having the tests in place, the following step is to write some code. Since you broke a test you need to fix it! Moreover, TDD suggests writing the simplest code possible, just to pass the tests in place. Particularly, Kent Beck [Kent, 2002] suggests to “Fake it until make it” which implies even returning constant values in order to make the test succeed. As a result, you will never implement something that you are not going to need (YANGI) but you will implement “just enough” to pass the tests. Once the tests and the implementation are in place you need to run the tests and get the “green light”, meaning that all code must pass the tests. Now you need to step back and think about it. You’ve started with failing tests in the morning, you wrote the least possible code at lunch time and in the evening you have a fully working and tested program. Doesn’t this makes you more comfortable? Doesn’t it make you feel more productive? Apparently, that is the point. Of course, you don’t feel that comfortable because even if your code passes the tests you know that you forced it to. For this reason, the next step is to refactor the code. This is the time where you have to apply your favorite software quality standards and principles, while having already the design and the documentation in place, which makes it a lot easier. At last, since you’ll make the tests run again, the implementation always implies new tests. Due to that, you have to go again from step one and follow the development circle.

Benefits
As can be seen from its definition, the benefits of TDD are numerous, from software design to developer’s psychology, and from software requirements to testing and high coverage. Personally, I believe that this technique can often lead to a more reliable software. To begin with, when a feature is finished, most of the time managers force developers to move fast to the next one since the first one “works”. However, the feature is not fully tested which eventually affects its safety. Thus, using TDD you ensure that your feature is already tested with high coverage. Other than that, TDD significantly improves the design. As Ward Cunningham mentions “Test first coding is not a testing technique”. Moreover, Kent Beck presents [Beck, 2001] that TDD offers more than just simple validation of correctness, it can also drive the design of a program. TDD is thus an analysis and a design technique since writing tests before the code requires to consider the design of the solution. In my opinion, this is a good technique to avoid the “analysis-paralysis” effect. It forces you to think about the design, which is considered a topdown process, but during writing tests, which is a bottom-up process. Consequently, it introduces a middleout process which can positively affect the tests, the design process and the developers productivity.

Limitations
So now that your confidence and the test coverage are high and your designs are good, it is time to mention that TDD does not always work. As presented in the previous paragraph, TDD “ensures” reliability, but apparently not always. This is why, most of the time the same developers who write the tests, also write the code. Because of that, the possibility of leaving “blind spots” in the implementation is very high, since the developers are “biased” with high confidence towards their code correctness. The developers think that everything has been tested and feel comfortable about it. However, there are a lot techniques to solve this problem. For instance, test coverage frameworks that analyze to which extent the code has been tested, or random testing that checks cases that you never thought about. In addition to that, there is always the case where the requirements were elicited the wrong way, and in this case you have a perfectly working and tested software, but the wrong software. Furthermore, as it can be seen [Oram and Wilson, 2010] [Beck, 2001] TDD is not applicable in cases that require a lot of functional testing, for example in GUI testing. Additionally, there is no recommended best context for the use of TDD. Thus, TDD can not be used as a framework for specific cases and, when applied, it can not always ensure that the best option, since TDD is difficult to learn. It involves a steep learning curve that requires skill, maturity and time [Oram and Wilson, 2010]. From my experience, you need to invest a lot of time in order to learn TDD, and even some more to practice it before applying it. Generating some personal “heuristics” and patterns that will make your work-flow easier will help. Despite that, once you grasp it, it is easily applicable and provides you with all the aforementioned advantages. Eventually, if not TDD itself, some of its variants, help a lot on many difficult situations. One of those TDD variants is Acceptance Test Driven Development (ATDD). Whereas TDD is a tool for well written unit of code, ATDD is a communication tool for requirements that are well defined. I believe that applying ATDD is a good practice since it does not affect the quality of your code, it is not time consuming, most of the times at least, since you usually test only the APIs, and it can make sure of the validity of the requirements, something that is a problem in the case of TDD. I personally use ATDD a lot. Following ATDD there is also BDD, Behavioral Test Driven Development that focuses on tests which describe behavior. Empirically speaking, there is evidence [Oram and Wilson, 2010] which suggests that on one hand, TDD strongly favors external quality and the modularization of an application, but on the other hand it negatively affects the productivity. Because of the steep learning curve, in the beginning it decreases productivity and introduces a lot of initial overhead. However, I believe it that despite that, it significantly increases productivity overtime, because of the end result is both running and tested software.

Conclusion
Test Driven Development is a very controversial topic in software process. Its costs are usually unknown which makes it an ambiguous technique to use. Online you can find fighters from both fields, favoring or opposing TDD with numerous success and failed stories. In the end it is a nice idea which provides great insights. As agile suggests, “adjust”, try it, and adjust it to your work-flow. If it does not work, change it.

References
[Beck, 2001] Beck, K. (2001). Aim, fire. IEEE Software, (5):87–89.

[Kent, 2002] Kent, B. (2002). Test driven development: by example. Boston, Massachusetts: Addison-Wesley Professional.

[Oram and Wilson, 2010] Oram, A. and Wilson, G. (2010).

Making software: What really works, and why we believe it. ” O’Reilly Media, Inc.”.