Avoiding Mini-Waterfalls

A lot of people and organizations, when transitioning from a serial software development lifecycle toward an Agile one, fall into the pattern of mini-waterfalls. They start doing iterations, but each iteration resembles the development lifecycle they already know. The programmers do some design work, then they write the code to implement the design, then unit test the code, and then they pass it to the testers for testing. To many people, this is the only way it can work. Their mental model only admits to this series of phases.

And they run into typical problems. Sometimes the design doesn’t fit the problem well, and patches are needed because there isn’t time to go back to design. The testers get squeezed for time at the end of the iteration, and no one knows how to accommodate the rework when a problem is found. More patches are added, because there isn’t time to redesign. And the next iteration starts the cycle over again.

Sure, doing this in two to four week cycles beats doing it in six to twelve month cycles. But only a little. Most of the time, it starts to fall apart if the team doesn’t learn to work differently.

But it’s inevitable, they say. (Continued)

I feel better, now

Oops! The whole problem started when I wanted to install a new program on the “entertainment computer” that’s connected to the TV. The existing version of Ubuntu was no longer supported, so I started what I thought would be a simple upgrade. Oops, it deleted the entire /var directory, including the contents of the second drive mounted there. That drive contained all of our photos and music. Not a problem, I thought. It’s all backed up nightly onto a USB drive. It’s just a bit of bother to copy all of that over the USB interface.

Oops! There are no photos beyond last March. I felt sick to my stomach. That’s a lot of family memories to evaporated. Whew! The program we’ve been using to download the cameras also makes a backup copy local to the machine used to download. I’ve got all the pictures back on the photo server, and now just have to sort them into directories again.

But first, I need to fix the backup script. Why didn’t it warn me when it started to fail? (Continued)

Tips and Advice: Test Driven Development

Yesterday, Bob Payne published one of our informal Tips and Advice discussions on the Agile Toolkit. Check out our Test Driven Development podcast and let me know what you think.

The Code of Christmas Past

When we write code, we’re often thinking about the short term. We need this code to function correctly so we can deliver within our immediate deadlines. I’ve found it important to also think of the long term. Sooner or later, we might encounter our own code, again.

I spent a chunk of my career where I often worked solo on projects that might get enhanced every year or two. This taught me a lot about the importance of code readability and what sort of things helped me quickly understand and avoid overlooking important considerations. I’ve also worked on a lot of legacy code bases, so I’m well aware of the pain and problems created by code that’s not readable, or is not organized in a helpful manner. (Continued)

Don’t You Have to LOGIN first?

In my previous post, Avoiding Iteration Zero, I suggested starting with “the one obvious thing that needs to be done? (Hint: it’s not ‘login.’)” As Jon Kern has recently mentioned, this same topic has come up elsewhere. I was also in that list discussion.

Jon is, of course, right in a narrow sense. You can start with login, if you want. You can also start with an Iteration Zero. (Or, an Iteration Minus One, as I’ve seen one organization do when their list of pre-planning outgrew one iteration.) I’ve observed that you can generally get better software, faster if you start somewhere else.

There are some very good reasons for this. (Continued)

Building sand castles on a rising tide

Grabbing a handful of wet, saturated sand, I let it dribble through my finger tips.  I watch each drop pile on top of the previous, draining away the water and leaving a new building block of solid sand.  Too much water and the previous drip will be washed away.  Too little and the sand cracks and refuses to hold together.  I watch the sand grow, getting into a rhythm that ensures just the right amount of water, without thought.

My thoughts are not on the mechanics of building a drip castle with sand.  Instead, I’m thinking of the spire that I’m building.  Can I build these two spires toward each other and form an arch?  Can I make this slender spire taller?

Frequently I fail and a part of the castle slides down, becoming part of the landscape again.  Or becoming a foundation for a new part of the castle.  No matter.  It’s the building of the castle that brings me joy–not the owning of it.  For I will never own it.  The sea soon comes and takes it away.

Last weekend, I drove six hours down to Floyd, Virginia for a Code Retreat organized by Gustin Prudner and led by Corey Haines.  There, I joined thirty-some people working in pairs and threes on Conway’s Game of Life for forty-five minutes at a time.  Then, Corey would call time, and we would wash away all traces of what we’d built.

Does that sound like a waste of time?

(Continued)

Testability & Good Design

Much of the time, the test-driven development yahoogroup is pretty quiet, but it has recently awakened from winter hibernation.  The question “Is it OK to add code to a class only to improve its testability?” stirred up a wide-ranging discussion that brought in the topic of what constitutes good design.  “Uncle Bob” Martin drew a bold line in the sand with his comment,

One reasonable definition of good design is testability.  It is hard to imagine a software system that is both testable and poorly designed.  It is also hard to imagine a software system that is well designed but also untestable.

I greatly sympathize with this statement, though I wouldn’t go quite that far.  I don’t think it is so hard to imagine code that is testable, but poorly designed.  For a trivial counter-case, there could be rampant duplication of testable code.  I would call that poorly designed, but it doesn’t affect it’s testability.  Therefore I would soften Uncle Bob’s definition to “One reasonable component of the definition of good design is testability.”

To me, the notion of “testable code” is the same thing that “testable circuit” was back when I worked on a custom integrated circuit.  Mostly, that depends on the ability to put the circuit or code into a known state, exercise it, and see the interactions with its collaborators and its resulting state. (Continued)

Test-driving those “non-functional” stories

The term “non-functional requirements” has always bothered me. “Do you mean the software isn’t supposed to work?” ;-)

This post is about how I approach test-driving the solution to non-functional requirements such as performance, and how it differs from test-driving a functional user story requirement. (Continued)

TicTacToe

Jeff Langr requested a Blog Pair for a tic-tac-toe program that he says “screams out for refactoring.” I looked at the code, and didn’t see an easy way to refactor it given the fragment posted. I did, however see a different solution. (Continued)

What Test-Driven Development is…

I know this has been bandied about hither and yon by lots of people. But I still see statements like the one by James Bach quoted on Matt Heusser’s blog that “the part of the testing problem they address is a small fraction of the whole.” Well, yes. Of course it is.

Maybe that’s because Test-Driven Development (TDD) isn’t a testing technique. It’s a software development technique that happens to create a safety net of unit tests.

Or, to paraphrase Captain Jack Sparrow, (Continued)