views:

525

answers:

9

I am on a team where i am trying to convince my teammates to adopt TDD (as i have seen it work in my previous team and the setup is similar). Also, my personal belief is that, at least in the beginning, it really helps if both TDD and Pair Programming are done in conjunction. That way, two inexperienced (in TDD) developers can help each other, discuss what kind of tests to write and make good headway.

My manager, on the other hand, feels that if we introduce two new development practices in the team at once, there is a good chance that both might fail. So, he wants to be a little more conservative and introduce any one.

How do i convince him that both of these are complementary and not orthogonal. Or am i wrong?

+5  A: 

Suggest that they read these books on TDD:

Michael Feather's Working Effectively with Legacy Code
Kent Beck's classic Test-Driven Development - By Example
Gerard Meszaros' xUnit Test Patterns - Refactoring Test Code
Test-Driven Development in Microsoft .NET

or these websites in pair programming:

Pair Programming (Wikipedia)
Corey Haines
Pair Programming Illuminated

Lucas McCoy
Thanks for the suggestion. i have read the first two myself and i have tried TDD and Pair Programming in a previous team and its worked for me. I should introduce these to my current team.
Anirudh
See also [this compendium of video and podcast resources](http://stackoverflow.com/questions/387326/unit-testing-videos-or-pod-casts/388485#388485)
Ruben Bartelink
+1  A: 

You don't convince. Tell him the reasons you think both work together, maybe present some data that confirms this, and let him decide. If you need to convince everyone that it's a good idea, I'm betting that no one is going to take to it too well. Natual opposition.

Josh Smeaton
+2  A: 

You are absolutely correct that pair-programming will help immensely when learning something new. I agree with you that you should push hard for doing both.

Perhaps the best way to lay it out for your manager is not to suggest that you're asking to introduce these two new things at the same time. Instead, suggest that you feel the most efficient way to start implementing TDD is, while still getting work done, is to take just two developers as the "TDD investigation team" and have them work together to get the appropriate tools set up, learn the techniques, test them, and figure out what you need to do to apply them in your environment. Once you've got that working, and have two people that have a bit of experience with it, then have them split up and each sit down with another developer for a few days to bring that other developer up to speed on the new techniques. Repeat until all developers have learned TDD.

Curt Sampson
Good idea. Thanks!
Anirudh
+7  A: 

I'm not sure that having more people who don't know what they're doing in TDD is going to help. It'll quickly descend into both of you Googling the subject, or both of you arguing over exactly what TDD is/isn't.

I think you'd be better of getting someone on the team to become the evangelist for a given technique (someone goes and reads up on TDD, somone goes and reads up on pair programming) and have those people then promt and trial those things. Yes, both can happen at the same time, but they don't have to be used throughout the project team. You could have a small group of your team do pair programming and then report back on their experiences.

Martin Peck
You are right. We are attending a workshop on TDD. So, that should provide a decent platform from which to start practicing it. I like the idea of trying it out in smaller groups and then propagating it slowly. Will try it out. Thanks!
Anirudh
A: 

Well, depending on the manager, you can point to some arguments in the XP literature that these practices are interdependent. For example, if you don't have solid unit tests, don't refactor mercilessly.

I would suggest you approach it incrementally, in that the pairing would only be for the purpose of figuring out TDD, like any collaborative effort on a new difficult problem, not that "all production development will be done in pairs."

Yishai
A: 

While one practice does not require the other, there is a 'sneaky' way to introduce both a little bit at a time.

Start with the goal of implementing TDD using one of the available xUnit frameworks. Find a compatible co-worker and ask if for about an hour a day they would be willing to work with you. "Shawn, I am trying this new tool, would you help me out to make sure I am doing it right?" works really well.

After a couple of days with Shawn, repeat with Susan...

Gary.Ray
A: 

Do it anyway. If the manager catches you pairing, say the magic words "Code Review"
Assumption: Obviously the pair should be disciplined/focussed enough and produce working code at the end of the session

Gishu
+1  A: 

Personally I have found pair programming works best with one experienced and one inexperienced.

Ie I would aim for a difference in skill/exp of programmers rather than trying to match evenly skilled.

the more experienced gets more out of it from explanation and being forced to structure thoughts whilst the inexperienced gets chance to bounce ideas and pick up 'best practises'.

as for TDD, i'm a big fan. Again exp helps the inexperienced because it helps really bring out the point of the testing. Ie you don't want to test absolutely everything ... it adds focus. Often I find people are writing tests without focus on what they are trying to achieve.

Unit tests are essential imo ... afterall, some staff wont be there in 2 years time. How can you alter the existing code if there is nothing to verify its function against?

John Nicholas
I've found the opposite: pair programming between two equal developers produces excellent code fairly quickly; pair programming between two developers of very different expertise levels either devolves into training, and not much gets done, or devolves into the more experienced programmer doing no better than working alone because the one with lesser experience can't keep up, much less contribute.
Curt Sampson
This. Have one programmer who is experienced in TDD pair up with someone inexperienced in TDD, and show him the ropes. When she has taught him to be reasonably competent at TDD, they each go off and pair up with another newbie.
Adam Jaskiewicz
There are different skill sets required in many development environments and I doubt you have two developers who are equal in all areas. On a specific task, they may be equal, but eventually they are going to run into a situation where one has more expertise.
Jeff O
+3  A: 

Pair progamming is a strongly recommended when learning a new practice especially TDD

So, you can have both with a compromise. Do this in an agile fashion, incrementally. Take on pair programming first. It is the easier of the two. All practices after pair programming will become much easier to learn and will be adopted by the team more quickly and with greater consistentcy. Pair programming is one of the first if not the first engineerring practice that should be adopted. Make sure it is done effectively. Below is a description of how to do pair programming.

Paired programming is one of the most potent practices a development team can practice when developing software. Pairing occurs with two developer actively develop a story card using a single computer and keyboard. Managers worry that using paired programming will double their programming costs. At first glance, it is understandable why they might think that -- after all --two developers are being asked to work together on the same task. In practice, though, Agile teams using this development technique have found that the slight increase in costs for the initial development (15% according to a University of Utah study) are more than offset by a reduction in defects, a shorter and less expensive testing cycle and reduced need for production support.

While it may seem counterintuitive that having programmers pair and work together improves productivity, there are a number of reasons why this technique really does work (Think of the old saying, "Two heads are better than one.") Here's why:

  • Improved quality -- Pairing encourages code review. Many mistakes get caught as they are typed. Paired programming means continuous code review done by two people who are committed to the quality of the code and are working together to identify and fix bugs at all times. A study done by the University of Utah found that the end number of defects found in code was reduced by 15% on average for the code written by pairs.
  • Less Time Spent "Stuck" -- Programming is hard. Often developers struggle to find a solution and spend more time than they should "stuck". Having a partner to brainstorm ideas with and to agree to seek help if necessary reduces the amount of unproductive time spent stuck trying to find a solution.
  • Less Time Spent on Distractions -- A developer is less likely spend time on personal phone calls or surfing the web, or email vacations when he or she is working with a partner.
  • Two Perspectives are Applied to the Problem -- Differing levels of experience, different problem solving styles, different auxiliary skills all increase the chances of solving a problem faster. The study done by the University of Utah also identified better overall design and shorter code length for the software written by pairs.
  • Less Fear of the Unknown -- When pairing with another developer it is easier to tackle a problem or try to get a handle on new technology than it is when working alone. They also gain, over time, a much better understanding of the entire application. In the end, the project ends up with multiple people understanding each piece of the system as a result of pairing.
  • Less Likely to Build in Scope -- Often developers willingly add functionality not addressed in the requirements. When working with a pair, the second developer is more likely to keep his/her partner on task.
  • Improved Team Dynamics -- Because of the paired approach, people learn to work together. They talk more often and experience a better flow of information. Team dynamics improve as a result. In fact, we have found that the best team building experience around is working together to produce software your customer is excited about. Everyone loves being part of a successful team.
  • Elimination of Silos of Knowledge – Domain knowledge, knowledge of the code or practices are quickly propagated through the team and developer pair with one another on a rotation basis.

Once the team is confortable with pairing, then take on TDD. A destription follows:

Test-Driven Development (TDD) is a software development engineering practice consisting of short burst of development where a new test case covering the desired improvement or new functionality is written first, then the production code necessary to pass the test is implemented, and finally the software is refactored to accommodate changes. The availability of tests before actual development ensures rapid feedback after any change. Practitioners emphasize that test-driven development is a method of designing software, not merely a method of testing. Test-driven development is a powerful practice and a major contributor to the reduction of defects found later in the life cycle. A new team is strongly encouraged to pair with an experience TDD practitioner or otherwise receive TDD coaching.e

Test-driven development requires that an automated unit test, defining requirements of the code, is written before each aspect of the code itself. These tests contain assertions that are either true or false. Running the tests gives rapid confirmation of correct behavior as the code evolves and is refactored. Testing frameworks based on the xUnit concept provide a mechanism for creating and running sets of automated test cases. Test-Driven Development Cycle: The following sequence is based on the book Test-Driven Development by Example, which many consider to be the canonical source text on the concept in its modern form.

  1. Write a test. In test-driven development, each new story card begins with writing a test. This test will fail because it is written before the feature has been implemented. In order to write a test, the developer must understand the specification and the requirements of the feature clearly. This may be accomplished through Story Cards with acceptance criteria to specify when the requirements has been meet. This could also imply an invariant, or modification of an existing test. This is a differentiating feature of test-driven development versus writing unit tests after the code is written: it makes the developer focus on the requirements before writing the code, a subtle but important difference.
  2. Run all tests and see if the new one fails. This validates that the test harness is working correctly and that the new test does not mistakenly pass without requiring any new code. The new test should also fail for the expected reason. This step tests the test itself, in the negative: it rules out the possibility that the new test will always pass, and therefore be worthless.
  3. Write some code. The next step is to write some code that will cause the test to pass. The new code written at this stage will not be perfect and may, for example, pass the test in an inelegant way. That is acceptable because later steps will improve and hone it. It is important that the code written is only designed to pass the test; no further (and therefore untested) functionality should be predicted and 'allowed for' at any stage.
  4. Run the automated tests and see them succeed. If all test cases now pass, the programmer can be confident that the code meets all the tested requirements. This is a good point from which to begin the final step of the cycle.
  5. Refactor code. Now the code can be cleaned up as necessary. By re-running the test cases, the developer can be confident that refactoring is not damaging any existing functionality. The concept of removing duplication is an important aspect of any software design. In this case, however, it also applies to removing any duplication between the test code and the production code — for example magic numbers or strings that were repeated in both, in order to make the test pass in step 3.

Repeat

Starting with another new test, the cycle is then repeated to push forward the functionality. The size of the steps can be as small as the developer likes, or get larger if s/he feels more confident. If the code written to satisfy a test does not fairly quickly do so, then the step-size may have been too big, and maybe the smaller testable steps should be used instead. When using external libraries it is important not to make increments that are so small as to be effectively merely testing the library itself, unless there is some reason to believe that the library is buggy or is not sufficiently feature complete to serve all the needs of the main program being written.

Development Style There are various aspects to using test-driven development, for example the principles of "Keep It Simple, Stupid" (KISS) and "You Ain't Gonna Need It" (YAGNI). By focusing on writing only the code necessary to pass tests, designs can be cleaner and clearer than is often achieved by other methods. Test-driven development requires the programmer to first fail the test cases. The idea is to ensure that the test really works and can catch an error. Once this is shown, the normal cycle will commence. This has been coined the "Test-Driven Development Mantra", known as red/green/refactor where red means fail and green is pass. Test-driven development constantly repeats the steps of adding test cases that fail, passing them, and refactoring. Receiving the expected test results at each stage reinforces the programmer's mental model of the code, boosts confidence and increases productivity

Cam Wolff
Thanks for a great and detailed answer!
Anirudh