So How do You Introduce TDD into an Organization or Team?

There’s an interesting thread going on in the Yahoo TDD group started by Jay Flowers about introducing TDD to a large organization, and an interesting spawned thread about TDD without OO.  I made a tangential post last week that’s referenced – How much design before unit testing, and how much design knowledge before TDD?


I’m not necessarily the best person to ask about this because my experiences haven’t been typical.  More than anything else, the critical factor is an organization or team of developers that is open and willing to doing TDD.  Management support would be nice, but in the end it’s the developers who are going to make it succeed or fail.  I had it relatively easy because my introduction to TDD came as a consultant with ThoughtWorks, one of the leaders of all things Agile.  A key factor for me joining my present employer was their desire to adopt Agile processes.  The support for TDD was there from day one, at least from development management.  Add in a group of developers who all believe in TDD, or at least willing to give it a try, and you can achieve a pretty smooth adoption rate.   


Coming in and laying down the law, “You will do TDD starting now!” probably isn’t going to fly.  Actually, I’ll say it more strongly – TDD won’t take without some kind of consensus from the developers.


You might not have it that easy, but then again, the wealth of free information and TDD lore that’s available on the web and blogosphere dwarfs the information that was available way back in 2003 when I was writing hopelessly tangled tests.


A team bootstrapping itself will probably struggle at first.  For best results, you’re going to have to get some coaching to the TDD newbies.  Most people, myself included, struggle at first with TDD when you start encountering nontrivial enterprise development tasks like persistence and integration.  Brown bag sessions (especially if the team takes turns presenting) and training will help, but for my money, you want a sprinkling of people who can coach TDD and get them paired up with the folks who are new to TDD.  If you don’t have anybody who can coach, it might be worth the cost of bringing in an external TDD coach to work hand in hand with the team members.  Regardless of the experience level that your team has, I’d very strongly consider adopting pair programming as a way to disseminate knowledge.  One of the advantages of pairing is the propagation of tricks — IDE shortcuts, ReSharper features, and TDD idioms for testing code.  For example, I learned how to use NMock for unit testing with external dependencies by pairing with someone who was familiar with NMock.  As a direct result, I immediately got faster.  Even part time pairing will help. 


Going in to TDD, you’re going to want an open-minded attitude about the way you code.  In other words, start with an assumption that you will have to change the way you code and design software.  I certainly wouldn’t say that TDD is the silver bullet for perfect software designs, it’s more like a white glove test that finds all of the tightly coupled dirt and gunk in your design.


Learn Unit Testing First, or Go Straight to TDD


Jay Flowers talks about two camps in his organization, one camp who wants to concentrate on doing unit testing first before moving to TDD while a second group wants to go directly to TDD.  My vote is actually on going straight to TDD.  Most of the challenge in writing automated unit tests is writing code that can be tested.  Putting an emphasis on writing the unit tests first keeps testability (and hence a strong focus on loose coupling) in the forefront of a developer’s mind.  Retrofitting unit tests to existing code is hard, period. 


OOP as a prerequisite for TDD


On the Yahoo thread I linked to, several folks are challenging my opinion that TDD requires OOP by sharing positive experiences of doing TDD and Continuous Integration with VB6.  I’ll take their word for it, but doing TDD with VB6 reminds me of seeing an elephant fly in Dumbo.  You can write almost-OO code with VB6 (minus true inheritance), but as I recall you fight against the language quite a bit.  VB6 wants to be procedural.


Let’s pretend functional programming doesn’t exist (because I don’t know enough about it anyway) and that SOA is largely an orthogonal concept to OOP.  I’m on record as saying that a solid understanding of Object Oriented Programming is essential for succeeding with TDD on nontrivial applications.  I wouldn’t hesitate to recommend TDD to someone who is new to OOP, but sooner or later that same newbie will be held back if they’re not a strong OOP developer.  To defend that assertion, let’s go back to some first causes:



  1. I want to be able to quickly write small unit tests that can be coded in rapid order to maintain flow
  2. External dependencies can make unit testing much more difficult and/or laborious, not to mention slower

The two primary ways to create testable code is to be religious in assigning responsibilities to different parts of your code and isolating external dependencies behind swappable interfaces.  In both cases I think OOP has a far better story than purely procedural programming.  OOP allows you to use techniques like Dependency Injection and Mock objects to replace external dependencies with fake objects that behave in a known way.  Using best OO practices leads to code that is cohesive and loose coupling, exactly the kind of code that is easier to unit test.  What can you do with procedural programming?  Function pointers?  You’re certainly not going to be able to do the same kind of interaction testing we use with OOP, and that’s an awfully important tool to leave behind. 


The real enabler of TDD is writing code that exposes seams to unit test in small chunks.  As long as you can accomplish that goal, you’re going to be fine.  I just think that coding in an OO style gives you many more tools to create testable code.  If you can stay perfectly in the realm of state based testing and keep your functions small and relatively independent, I can see you being able to use TDD with procedural code.


Just for background, here’s an older post on State vs. Interaction Testing.  You’ll want to be able to do either, and know when each is most applicable.


 


P.S. I think doing TDD is actually a great way to learn OOP.  You get immediate feedback on your OO structure.

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Pair Programming, Test Driven Development. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://vikasnetdev.blogspot.com/ Vikas Kerni

    Here is my roadmap for introducing TDD,CI and OOP for Legacy Systems(or Existing Systems). It is about forcing TDD and CI down the organization’s throat whether organization likes it or not

    http://vikasnetdev.blogspot.com/2006/06/eight-point-checks-for-servicing.html

    http://vikasnetdev.blogspot.com/2006/06/what-if-we-can-maintain-our-software.html

  • Eric Nicholson

    Speaking from experience TDD in VB6 is very hard. I’ve been able to accomplish passable TDD with new development, but retrofitting existing code to bring it under test is painful.

    I read through the Michael Feather’s book hoping to apply some of it to VB6 and most of the techniques are impossible/impractical. The language just puts up roadblocks at every turn.

    There is definitely some benefit there, but don’t expect to turn a VB6 team into true TDD believers.

  • Brian Schmitt

    Carlton, Thanks for the link…
    Jacob/Carlton,
    Yes I do believe that there is a battle there, I feel that maybe the best approach may be to learn the prinicples, on projects I work on outside my employer, then once I have a firm grasp on the concepts, I may have the leverage I need to make it ‘valuable’ to the business….

  • http://www.weiskotten.com Jeremy Weiskotten

    I agree: a mandate from management isn’t enough to make TDD work. TDD is a culture as much as it’s a programming style. Developers have to WANT to do it. I think the best way to convince others to want to do it is to first talk about it, spread an understanding of the benefits and challenges, and ultimately get people to try it (ideally in pairs). The biggest stumbling block is our natural fear of change, and the solution is education.

    My company recently introduced TDD after incorporating a lot of other Agile practices over the past year. We trained about 300 developers over 6 weeks in TDD, bringing legacy code under test using some techniques from Michael Feathers’ excellent book “Working Effectively with Legacy Code”, and dependency injection.

    The class was a mix of presentation, demonstration, Q&A, and hands-on where people paired up at workstations with Eclipse. The feedback that we got was excellent and was used to improve the class over time, and we got the sense that people really wanted to do TDD.

  • Carlton

    Brian, I might suggest checking out James Shore’s “Change Diary” where he talks about “technology-first” changes and how it might be relavent to your situation.

    http://www.jamesshore.com/Change-Diary/Week-Sixteen.html

    It is his experience (and mine), if you do not have developer buy-in on a technique like TDD, it will never fly. I hope it works out for you, but I am doubtful.

  • jmiller

    Jacob,

    I certainly agree that TDD in VB6 could add value, I just think it sounds hard. My hats off to the folks that are making it work. I’d just rather stay in nice easy .Net world.

    Tomas,

    I didn’t talk about Functional languages because I don’t know very much about them, other than I *really* hated working with a monotonic rules engine. I’ve read a lot of people gush on about functional programming lately. I’d really like to see some samples.

    Jeremy

  • Jacob Eggleston

    Jeremy,

    It seems like your argument is more against VB6 than it is against TDD in VB6. For those poor souls who are still stuck programming in VB6, I would think that following the principles of TDD could still add value and stability to their apps.

  • Jacob Eggleston

    Brian,

    I can’t think of any way around having a reference to your testing framework of choice. But your unit tests should probably be in a separate project anyway, so what you might do is create a separate solution which would contain your regular projects plus the unit tests.

    Speaking from experience, you may end up fighting quite the uphill battle with your team, but good luck to you in your efforts.

  • Brian Schmitt

    I am interested in TDD, (but as part of a team who unfortunately is not)
    How do you proceed from there? We are a .Net shop and it seems as though all the frameworks require a reference set to the xUnit framework… How does an individual achieve this in a group setting? I feel that if I can show the value over time, I may be able to win over the rest of the team. Thanks for your help…

  • http://www.winterdom.com/weblog Tomas Restrepo

    Jeremy, I won’t argue with you about VB6, it was definitely a clunky beast :)
    That said, I think you’re narrowing your vision of non-OOP a little bit too much if all you consider outside of it is just VB6. Frankly, I don’t see why TDD wouldn’t work (and indeed work very nicely) with functional and logical programming languages like haskell or prolog. At least, you can be pretty sure they are pretty well more suited to “keeping your code small and relatively independent”.

    Then again, it’s just my very humble opinion :)