« May 2008 »
S M T W T F S
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Where's Dave?
Mobile version


Monday, 5 May 2008
Package deal
Topic: Value proposition

The rising cost of gasoline and diesel fuel has become a hot issue in the United States. Independent truckers and ordinary working people are feeling the pinch. They are looking for ways to maximize the value they receive from each gallon of fuel they purchase. CNN aired a report recently that explained the benefits of certain actions we might choose to take to maximize the value of our fuel purchases:

  • Clean air filter: Saves 35 cents per gallon.
  • Alignment: Saves 35 cents per gallon.
  • Reduced highway driving speed (>60 mph): Saves 25 cents per gallon per 5 mph reduction.
  • Engine tune-up: Saves 14 cents per gallon.
  • Correct tire pressure: Saves 10 cents per gallon.
  • Excess weight carried in the vehicle: Saves 7 cents per gallon per 100 pounds.
The figures are based on average fuel consumption for a passenger car using gasoline. A driver who takes all these actions will save about $1.26 per gallon (assuming they take all the recommended actions, drive just 5 mph slower, and remove 100 pounds of excess weight), or $16.38 for a typical economy car tank of 13 gallon capacity (based on Toyota Corolla). If the price at the pump is $3.75 per gallon, then this driver is effectively buying gasoline at $2.49 per gallon. Assuming the driver buys two tanks of gasoline per week, the yearly cost without taking the efficiency measures is $5,070. With the efficiency measures, the driver spends about $3,366.48 per year, for a savings of $1,703.52.

If a driver did only the simplest things on the list, and didn't bother taking the vehicle to a shop to have the alignment and tune-up done, then the annual savings would amount to about $0.77 per gallon, or $10.01 per 13-gallon tank, or $1,041.04 per year. Of course, your mileage may vary (YMMV) — literally — based on what sort of vehicle you drive and how badly you were managing your driving habits originally. In any case, the general benefits are clear. Whether you go ahead and do everything to get the maximum economy from your fuel budget or just do the easiest things, it looks like a no-brainer, doesn't it?

Certain software development practices are well-known to improve the effectiveness of project delivery. Some of these practices are very easy to implement and others require a bit more effort. Certain combinations of effective practices have been organized into comprehensive methodologies in a way that mitigates the weaknesses of each practice while maximizing the value added. Whether you go ahead and adopt a comprehensive agile methodology such as XP or just do the easy things to get the maximum value from your software development projects, it looks like a no-brainer, doesn't it?

Why, then, do so many people continue to engage in circular debates about the effectiveness of well-known software development practices? Arguing about whether TDD "works" better than hacking up some code and then "testing" it in an ad hoc, manual fashion seems a lot like arguing about whether a clean air filter "works" better than a dirty one. Isn't it self-evident? YMMV still holds, but even if your team doesn't get the best imaginable mileage from using good practices, it will definitely gain some improvement. Why would anyone in their right mind not do it?

 


Posted by Dave Nicolette at 11:36 AM EDT
Updated: Monday, 5 May 2008 4:25 PM EDT
Post Comment | View Comments (16) | Permalink

Monday, 5 May 2008 - 6:14 PM EDT

Name: "Carlton Nettleton"
Home Page: http://www.carltonnettleton.com\blog

Because it is not so "obvious".

Monday, 5 May 2008 - 6:43 PM EDT

Name: dnicolet1
Home Page: http://www.davenicolette.net/agile

You may be right. The benefits may not be obvious to reasonable people. I can appreciate that, since I used to be reasonable myself.

Monday, 5 May 2008 - 7:19 PM EDT

Name: "Ryan Hoegg"

You might think the value of TDD is self-evident because you are a neophilic monkey.

It wouldn't be self-evident if you hadn't tried it first.

Tuesday, 6 May 2008 - 8:29 AM EDT

Name: dnicolet1
Home Page: http://www.davenicolette.net/agile

Neophilic I may be,
but I think you must agree,
this photo (unretouched, you see)
proves I am a chimpanzee
and not a monkey, technically.

Tuesday, 6 May 2008 - 8:35 AM EDT

Name: dnicolet1
Home Page: http://www.davenicolette.net/agile

But seriously...

Ryan's connection with the primate experiments in neophilia is apropos. In a general sense, software development is somewhat akin to "manipulative and exploratory foraging" behavior, and those who are willing to try new things usually do better at it than those who aren't. I think the reason is that the neophilics get feedback from their experimental efforts very quickly, they learn empirically what works and what doesn't, and they are more ready than their troop-mates to hone what works and discard what doesn't rather than keep doing things the same way just because that's the way we've always done it.

 

 

Friday, 9 May 2008 - 12:38 PM EDT

Name: "Malapine Lefou"

Because doing TDD on a typical (poorly-maintained) codebase is much like doing a front-end alignment on a typical (poorly-maintained) automobile.

It costs a lot more than doing nothing;

It requires tools and skills a non-agile team doesn't have;

and the payback is not obvious or immediate.

Sunday, 11 May 2008 - 10:47 AM EDT

Name: "Dave Nicolette"
Home Page: http://www.davenicolette.net/agile

Malapine,

Thanks for posting a beautiful and concise list of common misconceptions that helps make my point for me.

An alignment on a poorly-maintained automobile improves the state of maintenance of the automobile immediately and in a way that is very obvious to the driver. Been there, done that.

The assertion you make about the cost of doing nothing is incorrect. The cost of allowing technical debt to grow (that is, to do "nothing") is greater than the cost of controlling its growth. The best time to begin to address the problem of technical debt is "now." A longer explanation is available here. We will be presenting that session from time to time in 2008. Maybe we can discuss it in person, and take into consideration the particulars of your situation.

Regarding tools, isn't it true that all the "major" toolsets for building business application software include tools to support TDD out of the box — Java, .NET, Ruby, and Python? Isn't it true, furthermore, that if a team isn't satisfied with the out-of-the-box TDD support, it's extremely easy to obtain alternative tools, like TestNG, JBehave, rspec, and so forth? Isn't it true that some of the other basic tools associated with agile development are just general development tools that have been known to be of high value for many, many years, and that are probably already in use on any team that's worthy of being called a "software development team" at all, whether agile or not — version control, continuous integration servers? I don't think the necessary tools are missing, even in non-agile organizations.

Regarding skills, it seems to me the main issue is, simply, awareness or mindfulness. After I published the results of this little exercise on the client company's internal wiki, several of the company's staff members told me they had taken the initiative to clean up existing code, that it wasn't as hard to do as they had feared, and that the benefits were immediately obvious.

One of them told a story that suggests the whole idea of TDD isn't really as odd as some people seem to believe it is. I happen to agree with him — most of this "agile" stuff is really just common sense. The problem is that we've all been trained and indoctrinated for many years in methods that are not common-sensical, and we've come to accept them as the norm.

I personally know several individuals working at that company who have adopted TDD as their preferred way to write code, and they do so even when they're assigned to non-agile teams on which their teammates don't understand the value of TDD. There are, in fact, no real barriers to doing TDD for anyone who chooses to do so, even when they are working in a non-agile context. The tools and skills are all around us. The only obstacles still remaining, really, are excuses.

I may be mistaken, but I have to wonder whether your conclusions are based more on assumptions than on direct experience. If so, then all I can say is: Try it.

Sunday, 11 May 2008 - 10:43 PM EDT

Name: "anonymous"

Regarding tools, isn't it true that all the "major" toolsets for building business application software include tools to support TDD out of the box — Java, .NET, Ruby, and Python?

Alas, this is systems programming, in C++, on a legacy codebase bought from another company (utterly sans tests). I have Fowler's "Dealing With Legacy Code", but it's not helping yet. I have made a stab at characterization tests; but the code is a mess, doesn't do what the limited documentation claims it does; and we have no PO or customer proxy to tell us what it /should/ do.

Monday, 12 May 2008 - 4:55 PM EDT

Name: "Dave Nicolette"
Home Page: http://www.davenicolette.net/agile

I've heard of this situation from a lot of people in the embedded systems space, too. I think you can enjoy some benefits from applying TDD to that codebase, but you're probably going to have to build some of your own tools and you can look forward to some significant refactoring to make the code more amenable to unit testing. Whether it's worth the effort to do that is your call. 

C++ is not my specialty, but if you want to drop me a private email I can suggest someone who might be able to help get you started.

Wednesday, 14 May 2008 - 9:08 PM EDT

Name: "Vladimir Levin"
Home Page: http://vladimirlevin.blogspot.com

While I am personally a proponent of TDD, I don't agree that TDD is a no-brainer as you seem to be suggesting. First of all, *how* to do TDD seems to be a much disputed question. For example, I am not a great fan of TDD which makes extensive use of mock objects, yet there are people out there for whom mock objects are a part of most tests they write. I would personally consider not having tests to be an improvement over having mocks all over the place.  Now, it's true that one gains experience as one does TDD, and that a team would hopefully develop their own style of TDD that they're happy with as they go along. Nevertheless, if you aren't experienced with TDD already, you probably shouldn't apply it to a project of any significance. In other words - start small and work your way up gradually to larger projects. I wouldn't recommend that a team with little experience doing TDD ought to start using it on a significant project, even with a mentor. I really believe it may well end up doing more harm than good - creating a large set of slow, brittle, and hard to understand tests that will just end up slowing down development. Having a mentor may seem like a solution to this problem, but again, there are lots of different ways to design using TDD, and the mentor you choose may not have a style that's compatible with that of the team. Until TDD becomes a really clearly standardized practice, if it ever does, there will be no solution but for individual teams and companies to gradually evolve their own best practices.

Another interesting phenomenon I've noticed with respect to TDD is that the most advanced developers I know consider TDD to be a useful technique, but one which has its limits, and they don't apply TDD to all of their development. I am a mid-range developer who's main experience is business systems, and in that realm I consider TDD to be very useful for shaping most of the code, but it's true that the more your tests depend directly on the details of the implementation, the harder it is to radically alter such an implementation while maintaining the tests. In such cases writing larger-scale integration tests that are not directly connected to the shape of the code itself, may be a better way to go.

I appreciate your enthusiasm for agile practices, but my sense is that this enthusiasm is sometimes not sufficiently tempered.

 

 

Thursday, 15 May 2008 - 7:41 AM EDT

Name: "Dave Nicolette"
Home Page: http://www.davenicolette.net/agile

Hi Vladimir,

Thanks for your thoughtful feedback. I agree with your "take" on the overuse of mock objects, but that is only a tool and not fundamental to TDD as a technique. When I first learned about tools like EasyMock and jMock I used them extensively, but gradually reduced my use of them. I found that such tools encourage too much white box testing, while behavioral testing seems to be more effective in the majority of situations. Today, I rarely resort to a mocking tool as such, although I am disciplined about test isolation. There are times with a mocking tool is appropriate, and it's good to have such a thing in our toolbox; we just don't want to get into the mindset that "I have a hammer and everything looks like a nail."

With regard to mentors who aren't very good at mentoring, well, that's certainly a problem, but not a problem with TDD as a technique.

I must disagree that TDD is to be avoided on large or significant projects. The value it adds in controlling the growth of technical debt is so beneficial that it is well worth the effort to learn to use the technique. The larger or more significant the project, the more important it is to apply the most effective development techniques available. On a larger project, technical debt will be a proportionally larger problem. On a more significant project (by which I assume you mean more significant in terms of business value), the cost controls TDD affords are proportionally more important than on a trivial project.

Regarding differences in application, I think there is room for variation in style, but larger differences in application amount to more than stylistic choices by individual developers or teams. I see two causes for it. First, as you point out, not everyone fully understands how to do it. You mention brittle tests, and that's a consequence of doing it poorly, not an inherent flaw in TDD as such.

Second, TDD has continually evolved since it was introduced widely. Originally, the idea was simply to test "whatever might break." There was no imperative to write tests before code. The test-first approach came later, and has become more or less implied in the term, TDD. The idea of focusing on behavior rather than implementation details is another refinement that evolved over time. The present trend toward BDD reflects that advancement in the practice. Test-first development has also been extended beyond the unit test level, and we now try to work with executable requirements whenever that is feasible. I expect TDD, as well as other development practices, to continue to evolve and improve. As that happens, it's only natural that different people will be at different stages of understanding and application. It's as if we all started a marathon at the same point, and after 90 minutes we're all spread out along the course. The fact we aren't all at the same point 90 minutes into the race doesn't mean there's anything inherently wrong with "running."

I don't think TDD is the last word in development technique. We are constantly evolving our practices through experience. When TDD is superceded by the next advance in development technique, we would be well advised to change our habits yet again.

I've had similar experiences to yours with respect to experienced developers who consider TDD to be an optional technique. I believe the fundamental reason for this viewpoint is that most of us who are "experienced" gained the bulk of our experience before some of these highly effective development techniques became current, and we tend to be creatures of habit.

Keep up the good work and independent thinking.

Cheers,
Dave

Thursday, 15 May 2008 - 12:24 PM EDT

Name: "Vladimir Levin"
Home Page: http://vladimirlevin.blogspot.com

Just for the record, you mentiond BDD being an advance. BDD is a practice that focuses on development of code in order of "business value." As such, it seems to generally imply that one would develop code in a top-down fashion, with tests of high-level functions depending on mocked-out versions of yet-to-be-written lower-level functions. Since I don't like using a lot of mocks, I am not in favour of this type of development and I don't consider it strictly speaking an advance in the state of the art. I do appreciate the value of not writing code strictly in a bottom-up fashion, but I still don't like a pure top-down approach either. Personally I tend start by writing a test at a high level, and as I fill in the calls I expect that high level function to make, I pause to investigate those functions/classes themselves more closely. Often this means commenting out the high-level test and writing tests and implementation for the lower-level functions (and so on recursively). I find this approach to be a nice compromise between a pure top-down and a pure bottom-up approach to design, as I can start with a high-level view of what I accomplish, and at the same time I get to make sure that the code I am writing does not depend on phantom classes and functions that I haven't written yet. The process of writing lower level code can inform the design just as much as sketching he high-level code does. I do consider mocks to be useful in some cases, but not as a tool that is used as an inherent part of the design process of TDD, which is what BDD appears to be about.

 

Thursday, 15 May 2008 - 12:31 PM EDT

Name: dnicolet1
Home Page: http://www.davenicolette.net/agile

Hi Vladimir,

I'm not relating to your definition of BDD. Maybe I shouldn't have tossed out a thee-letter acronym, since they may have multiple meanings. I meant to refer to Behavior-Driven Development. There aren't any implications about top-down vs bottom-up or mocking. Sorry for the confusion.

Dave

Thursday, 15 May 2008 - 12:34 PM EDT

Name: "Vladimir Levin"
Home Page: http://vladimirlevin.blogspot.com

See http://en.wikipedia.org/wiki/Behavior_driven_development for example. 

 

Thursday, 15 May 2008 - 3:03 PM EDT

Name: "Dave Nicolette"
Home Page: http://www.davenicolette.net/agile

Hi Vladimir,

That's not a bad description. It appears to be drawn largely from Dan's own writing about BDD. Yet..."You keep using that word. I do not think it means what you think it means."

You write, "it seems to generally imply." Maybe it seems that way to you. Okay, I can't dispute your personal impressions of a thing.  Personally, I find BDD a powerful tool that adds value, and a logical evolutionary step in the refinement of the idea and practice of TDD.

At least, that's how it seems to me, FWIW.


Dave

Thursday, 15 May 2008 - 6:09 PM EDT

Name: "Vladimir Levin"
Home Page: http://vladimirlevin.blogspot.com

Dave, it's possible I am misunderstanding what BDD is all about. My general impression from what I've heard people tell me and from some casual reading I've done online is that in practical terms the test-first paradigm in BDD is shifted to be more of a "mock-driven" approach. You start a story by writing a test for the highest level function you can think of and specify its behaviour by having the test verify its interaction with mocked out versions of whatever objects the function under test will be interacting with. The actual code the function calls on other objects remains at this point unwritten - just an empty shell. The next step becomes to write tests for *those* functions in turn using the same approach until the lowest level of the code is reached. Of course this is not strictly top-down design, since as in all agile paradigms, development still goes in vertical strips - that is, by the end of a given story, *all* of the code for that story will be completed end-to-end and can thus be tested using integration tests (which may well also have been written ahead of time). I should retract something I said earlier: If in fact this is how someone does BDD, I consider it not to be so bad, even though I am personally not fond of the pervasive use of mocks. When all is said and done, I'd rather develop each story mostly bottom-up so that I won't have to mock anything out unless it's mandated by special considerations (e.g actual code will be written by someone else in the future; there are performance or configuration problems for running tests; code cannot be counted on to return same values for a given input over time...).

If your perspective on BDD is different from what I've described, how you do BDD may not be a bad topic for an upcoming blog entry!

 

View Latest Entries