(I originally posted this on my MSDN blog.)
About a year and a half ago, shortly after I discovered Scrum, TDD, dependency injection, mocking frameworks, design patterns, and many other shiny new toys, my team started a new project. Being the bright-eyed novice that I was, I said, “Hey, this would be a great opportunity to try out all these neat ideas I’ve been reading about! In fact, we should try them all at once!” And since I was the team lead, everyone else just kind of nodded and said, “Um, yeah, sure, whatever.” (That should have been my first clue.)
I’ll spare you the gory details, but suffice to say that we were playing with stuff we didn’t understand. I knew just enough to get myself into trouble, and the rest of my team had difficulty understanding what I was babbling on about, so there was a whole lot of cargo cult engineering going on. Looking back on it now, I think we probably got it about 75% right, but the other 25% made the whole experience very painful for everyone involved. We didn’t go quite to the extreme of level of building factory factories (I think . . . ), but there were many things in the code base that were over-engineered; either because they were needlessly complex or because no one knew how to take advantage of the complexity in order to deliver value.
Fortunately, the project was mothballed as a result of a reorg so we didn’t have to push it to its conclusion. I think it would ultimately have been successful. I could see a lot of promise in the techniques we were using. But there were so many new ideas jumbled together, and not implemented with a deep understanding of why they were good ideas, that we weren’t seeing the promised reduction in pain and increase in productivity. Quite the opposite, actually. To this day people still roll their eyes and chuckle whenever that project is mentioned.
I drew several lessons from that experience, but the main one is this: you don’t have to adopt everything all at once. There is a certain intrinsic rate at which a team can absorb new ideas while still turning out productive work. New ideas and new tools are usually disruptive. I don’t care how good the idea or tool is, there’s an inherent cost in taking it onboard. The cost of one or two at a time is manageable. The cost of several new things all at once can be ruinous. There’s a invisible line called “the maximum safe rate of change”, and you don’t want to cross it.
We backed off a bit on Agile techniques after that. We kept reading, learning, and experimenting, trying to build a deep understanding of the principles, not just the ceremonies, of Agile development. Turns out that real learning takes time and practice. Huh, who knew! It took about a year before I was confident enough to take another shot at running a seriously Agile-oriented project with more than two people. It was going very smoothly, I think, until the layoffs happened, which just goes to show, I guess, that engineering isn’t everything.
So anyway, that explains my previous posts on how to use context/specification in the MSTest environment. Why not just use xUnit.net and SpecUnit.net, or MSpec? Well, yeah, in an ideal world I would. I plan to, someday. But in the context of our latest project, we were wrapping our heads around the context/specification format and using an IoC container for the first time. Oh, and doing an in-place refactor/rewrite of a legacy code base. Switching test frameworks and test runners on top of that may have pushed us past our maximum safe rate of change.
There’s always tomorrow. Tomorrow may end up looking very different than expected, but learning never stops. Give new stuff time to sink in, to turn from pantomime to purposeful action, so it can be used to generate real value.