Geeks With Blogs
Blake Caraway
In a previous post I detailed some conditions existing on development teams that would suggest some changes need to be made in order to bring about better performance and ultimately higher quality software. In this post I will identify a couple more Team Smells and discuss how these issues can be remedied and why these conditions should be addressed in the first place.

Smell: Developers Spent Way Too Much In The Debugger (AKA Debugger Junkies)
A good feature-rich debugger like the one that comes with Microsoft Visual Studio is a nice tool. It allows you to easily get a view into the runtime state of your code. Unfortunately, developers can use this tool as the sole form of verification that the code they wrote is functioning properly. There should be one obvious, overriding reason to step through code using the debugger: tracking down a bug (duh!). A valid debugging scenario would entail watching a particular piece of code execute to determine why it’s behaving in an unexpected manner. A Debugger Junkie commonly works in this way:

  • 1. * fingers crossed *
  • 2. Hit F5 and see if the solution compiles
  • 3. Wait for the entire application to load up
  • 4. Navigate to the specific point in the application where the breakpoint or breakpoints are ready and waiting
  • 5. Interact with the application to try and re-create the unexpected behavior
  • 6. When Step 5 uncovers some indication as to where the problem might be, investigate the objects’ state in and around the perceived problem area to uncover the root cause
  • 7. Devise a plan for where the code should be modified to make the feature behave as expected
  • 8. Make code change and GoTo Step 1

  • Not only is this an unbelievably inefficient way to work, it can often make for a confusing and miserable work experience. No wonder developers on a team that exhibit these smells don’t want/are afraid to modify their code – they are sick of looking at it! Because of the dependency on the debugger to validate their efforts, by the time these junkies have completed a couple medium-sized application features, they are experiencing no small amount of frustration from the debugging monotony they have put themselves through. There _is_ a better way…

    Refactor: The key to ridding your team of this poor habit is to implement measures that help developers gain confidence in the code they are producing. Getting a development team to change the way they work and weaning them from the perceived security of the debugger can be a rough ride in the beginning. J. Peterman, of Seinfeld fame, said it best when demanding Elaine help her office ‘boyfriend’ Zach break his drug habit –

    PETERMAN: … Uh, P.S., the first twenty-four hours are the worst. Better bring a pancho.

    Yep, it can get messy. There will be no limit to the number of excuses offered up as to why this new approach won’t work. But Test Driven Development (TDD) is perfectly suited for ridding a development team of their debugger dependency. The very process of creating a unit test before writing any live code provides the developer with an accurate measurement of how the code should work. When code is written to make a unit test pass, there should be a large amount of confidence that the code is doing exactly what it needs to do. When all requirements for an application feature are satisfied by a battery of unit tests – THE FEATURE IS COMPLETE. Some other things have to change in order to for this approach to work. Separation of concerns among application layers and coding to interfaces across these layer boundaries must occur so that isolating code for unit testing can take place. Doing this effectively also allows developers to work without having every layer functioning – i.e. no need for a working, populated database, web services, or active directory services.

    When these dependency endpoints can be ‘faked’ through some sort of abstraction (like an interface), application logic can be created and tested effectively – one test at a time. When the time comes for a true build process and deployment to an integrated, end-to-end environment, there should be fewer surprises as to how the code works when it’s all put together – all because of the effort taken to develop test first and receive feedback from the very beginning regarding how the code is behaving. See Scott Bellware’s excellent post on TDD and failing tests meaningfully for a much more elaborate discussion surrounding the benefits of good unit tests.

    That’s it for now.

    Oh, and for no apparent reason, here are a few more Seinfeld quotes talking about Zach’s drug problem:

    PETERMAN: I'm afraid the problem with Zach is more serious. He's back on the horse, Elaine. Smack. White palace. The Chinaman's nightcap.

    PETERMAN: And, in a tiny way, I almost feel responsible. I'm the one who sent him to Thailand - in search of low-cost whistles. Filled his head with pseudoerotic tales of my own Opium excursions. Plus, I have him some phone numbers of places he could score near the hotel.

    PETERMAN: Damn it, Elaine. That wasn't Zach. That was the yam-yam. Now, he is going cold turkey. (Ordering) And you will be at his side. Posted on Thursday, March 30, 2006 2:13 PM TDD | Back to top

    Comments on this post: Team Smells...Refactoring For A Better Tomorrow (Part Two)

    # re: Team Smells...Refactoring For A Better Tomorrow (Part Two)
    Requesting Gravatar...
    Nice post, Blake
    Left by Jeremy on Mar 30, 2006 4:28 PM

    # re: Team Smells...Refactoring For A Better Tomorrow (Part Two)
    Requesting Gravatar...
    I haven't done TDD and basically I'm guilty of using your 8-step-debugger method. I've been resistant to TDD because I don't want to spend lots of time creating tests and abstracting layers which aren't a part of the final production code/solution. Also, I worry that somehow my tests would be either trivial or incomplete. How would I know I've made all the tests required? Let's say for example I make a widget that divides a value by 5.

    return x/5;

    I write tests for values 10, 20, 30 and get back 2, 4, 6 like expected. So I'm done! I release my code only to find I never checked for 0 which naturally causes a division by zero error.

    It seems to me that at it's best, TDD is a method which helps to reduce errors but is not able to guarantee bug free code. When TDD fails, aren't you back to compile-test-debug anyway? And if so, what value does TDD really add?

    Left by Brian on Mar 31, 2006 6:01 AM

    # re: Team Smells...Refactoring For A Better Tomorrow (Part Two)
    Requesting Gravatar...

    Thanks for the comment. Let me be clear on this: TDD does not guarantee bug free code. It is not a silver bullet that yields some sort of software development nirvana.

    In this post I'm trying to explain that exclusive/excessive use of the debugger as a measurement device is typically a sign that a developer needs a better mechanism to gauge whether his code works as intended - both at the time of development and going forward as the code base continues to grow.

    One of the big benefits of TDD is that it helps to ensure code is working as intended (as defined in the requirements/user stories). Dont' forget, TDD is a _design_ function, not a testing function. Using tests to write code promotes (nay, demands) that your code be testable from the beginning. When you are effectively using TDD, time spent firing up and stepping through code in the debugger just to watch it work decreases dramatically. The reason for this is that when you use TDD to design your code in a loosely coupled and cohesive manner, the passing unit tests indicate that the code under test is performing as it should at a very granular level. When you put the methods together to form a particular application feature, you have MUCH more confidence as to whether your code is "working" or not.

    Unit tests should not be the only form of measurement to determine the health of application code. Integration tests and user acceptance tests are other things that should definitely be used in addition to developer unit tests (created using the TDD process or post-hoc).

    The fact that you are doing some sort of automated testing is a big step in working smarter to ensure a sustainable code base going forward. The fact that a team is admitting and forsaking its old, busted inefficient code development processes is the first important step in improving the overall quality of the team.
    Left by Blake on Apr 01, 2006 7:59 AM

    # Blake Caraway continues on "Team Smells" - level 100
    Requesting Gravatar...
    It's a great read:Team
    Smells...Refactoring For A Better Tomorrow (Part Two) and if you missed the...
    Left by Jeffrey Palermo on Apr 03, 2006 6:32 AM

    Your comment:
     (will show your gravatar)

    Copyright © Blake Caraway | Powered by: