Throughout my career, people involved with software development and support have done their best to make software perfect; or at least to eliminate all the bugs from it. We’ve come up with more and more design principles, development techniques, testing methods, system monitoring and self-correction schemes, and tools aimed at avoiding, preventing, detecting, working around, recovering from, and removing bugs from software.
It’s a commonplace to say there is no “silver bullet,” and everything we do in the software field has to take context into consideration. In fact, this is quite true. TDD is a useful technique to know. To know TDD well, you must understand why and when it is useful, and how to do it correctly. If you apply TDD for the wrong reasons, in the wrong places, or in the wrong way, then it will not yield any value.
Many of the complaints people raise about TDD and about unit testing in general boil down to a misunderstanding or a misapplication of practices. Some complaints, however, are completely valid. You have to make your own professional judgments about such matters. To be equipped to make such judgments, you need to understand how TDD can add value in your work; and when it will not.
Continue reading Looking at TDD through a lean-agile lens
It’s a familiar adage among engineers, often posted in work areas. Does it pertain to software development? The seemingly endless circular debates about software delivery methods lead me to think so. The latest chapter in the ongoing drama is the recent schism between Lean Kanban University’s flavor of Kanban Method and the rest of the lean/kanban community. And the paint hasn’t yet dried on the sumo match between Kanban and Scrum. A few years ago (mid-00’s, as memory serves) the same debate (except for the names of the methods) raged between proponents of Evolutionary Project Management (Evo) and Extreme Programming (XP). Prior to that, we kept ourselves entertained by debating whether RUP was Agile. Before we could do that, we had to settle the debate about the relative merits of Spiral and RUP, of course. And Spiral vs. linear SDLC processes. Tomorrow, next week, or next month, it will be something else. Important questions, all.
Yet, I can’t help noticing, as Ron Jeffries puts it, it’s all the same elephant. When I stopped arguing and started listening to the elephant, I heard it say "Don’t do anything stupid on purpose." What does the phrase mean in the context of software development and delivery? To explore the question, I think it would be helpful to define the terms stupid and on purpose for that context. Continue reading Don’t do anything stupid on purpose
There’s no shortage of advice about best practices. Naturally, commercial enterprises like IBM and Construx have advice. Their advice is designed to lead people toward their products and services. Of course, that’s because they believe their products and services support best practices. After all, they designed their products and services on the basis of what they consider to be best practices. So, it’s all good, right? They’re financially successful, so we can trust them. Besides, everyone knows that commercially-packaged best practices are carefully designed and well proven.
Individual practitioners are also eager to share the practices they have found "best" in their work. Their advice can be helpful, provided we remember it tends to be opinionated ("Git:Mercurial = Assembler:Java" — not "practices," BTW); haphazard and idiosyncratic (not to mention sexist and poorly written); specific to a single technology (and poorly written); or a rehash of generalizations (supported by questionable references). Like this Wikipedia article (as of 24 July 2013), such advice "has multiple issues." Continue reading Best practices for software development
A while ago on this blog I mentioned the idea that a programmer’s job is not to deliver code, but to deliver provably correct code. Twitter responses ranged from strongly negative (wrong on so many levels I don’t know where to start) to mildly negative (not completely wrong, but incompletely right). There were no positive responses.
The converse of deliver provably correct code is deliver crap code, as I read it. Yet, it seems unlikely that is what those people meant to say. Unfortunately, no one followed up to explain their interpretation. I can only speculate that my choice of words has different implications for them than it does for me.
Since no one wants to explain their interpretation of the phrase, I’ll explain mine.
Garlic is widely considered to offer significant health benefits. It’s also a delicious and versatile ingredient in foods. Would tomato-based pasta sauce be pasta sauce at all if you omitted garlic? (Ignore American-style fast-food pasta sauce for the moment. Canadians, before you smirk, I have just two words for you: Pizza-Pizza.)
Chocolate, as well, brings a variety of health benefits. It, too, is delicious and a versatile ingredient in foods. What would a chocolate bar be if you omitted the chocolate? (Ignore "white chocolate" for the moment. Come to think of it, just ignore "white chocolate" altogether.)
Logically, then, it follows that chocolate-covered garlic cloves must surely be among the healthiest and most delicious foods one could hope for.
But why stop there? Glass is a wonderful material that adds much to our modern way of life. There is even a form of biocompatible glass that helps broken bones heal. Clearly, glass is good for the body.
Logically, then, it follows that chocolate-covered garlic cloves with tiny shards of glass embedded in them must surely be a super health food as well as a fabulously delicious snack. What an amazing rainbow of flavors and textures in the mouth! Ah, the sultry contralto notes of the chocolate, the lingering bite of the garlic, the metallic tang of the blood. And all of that still but a prelude to the inevitable conclusion.
The same logic applies to the task of selecting tools and methods for developing application software. I recall one project in particular that illustrates this approach quite well. The company wanted to maximize their chances of delivering a high-quality, well-aligned, usable product in a reasonable time. They went in search of the Best Practices Ever for delivering software, and identified three Good Ideas. Then came the flash of insight that set the stage for success: Combining all three Good Ideas on the same project could only result in three times the Goodness!
Well, in theory, anyway. In the immortal words of American philosopher Lawrence Peter Berra, "In theory there is no difference between theory and practice. In practice there is."
I consider test-driven development (TDD) to be a basic software development technique. I’ve used it in a wide range of circumstances for different types of applications in different domains based on different languages and tools. I coach people in using the technique, I run workshops at conferences on it, and I offer a two-day training class on it.
My only regret is that I didn’t learn about TDD earlier in my career. All those years doing things the hard way…time lost forever. Oh, well.
I use TDD and I like it, but I never try to “convince” anyone that they should use it, or even that it works well. I never suggest that TDD is a “goal” for an individual or for a team. TDD might help you achieve some other goal, but it isn’t a goal in itself. It’s just a technique.
And, let’s face it, nearly all the code in production today, worldwide, was developed without TDD. Nearly all the code under development right now is being developed without TDD. Clearly, programmers can get along without it.
Continue reading The right kind of lazy
I’ve heard it said that there are basically two ways to understand a thing: (a) by direct experience, or (b) through metaphor. People who need or want to understand software development, but who don’t develop software themselves, often rely on metaphor. They are like the six blind men who try to describe an elephant. (That was a simile, not a metaphor.)
Software development is a unique sort of activity, with its own distinctive characteristics. Yet, as a way to try and understand the nature of software development, people have used various metaphors to describe it. Software development is a wall, or a rope, or a spear, depending on which part of the elephant a non-developer happens to touch.
Metaphors are something like conceptual models. Little ones. As George Box wrote, all models are wrong, but some models are useful. The popular metaphors about software development are wrong. They are wrong because they do not capture the exact nature of software development completely. The metaphors are also useful. They are useful because each one of them does capture some interesting aspect of software development in terms that people can relate to.
Continue reading What is software development?
I have learned quite a lot from reading Lean Software Engineering, a website authored by Corey Ladas. Although I am not personally acquainted with him, I have gained a great deal of respect for his thinking and his experiences in applying lean principles to software development.
My growing respect for him may be the reason I was struck by a comment of his that I came across recently while browsing the site. In a response to a reader’s comment dated January 7, 2008, he wrote: “Pair programming is antithetical to Lean” It was just a flat assertion with no explanation.
I was puzzled. Lean software development doesn’t speak to particular development practices, as far as I know. What might cause a practice to be antithetical to lean or, for that matter, to support lean? The only basis I could think of on which to reach such a conclusion was that the practice either hinders or helps us in applying lean principles to software development. Corey did not provide the same level of careful analysis and explanation as he does with most of the useful material on his site, so I decided to reason through the question myself.