First off, I'll say, Hi. I'm Jiva, and I'm a
cowboy coder. I didn't used to think I was a cowboy coder, but some things
have happened lately that make it impossible to deny.In the end, I came to appreciate XP as a real enabler for coders to do what they love best, CODING. I became convinced it was an excellent tool to add to my arsenal of methodologies. I took it upon myself to educate my fellow coders, and spread the gospel.
And then one day, it happened. I became... a manager! But not just a manager... a manager for a project starting completely from scratch! With no baggage from previous projects! What a perfect opportunity to actually TRY XP in a real-world-environment!!
I educated the members of the development team I was herding^H^H^H^H^H^H^Hmananaging about XP. I taught them about test-first programming. I showed them the cost-of-change spiral. I brought index cards to every meeting, and we specced the project on those cards. I was an XP *machine*. I bought all the books and read them twice. I brought in local experts on XP to give us classes.
And in the end... the entire team saw that it was good, and everyone did their part to help implement it. People who previously hated methodologies and processes, were using XP every day. We built our own automated test environment, and we held to the policy, "100% of the tests run 100% of the time!!!" If the code we were working on didn't run 100% of the tests, it didn't get merged into the development tree! The work was spread out amongst us, so that no one person could diverge far from the main tree without merging. I was very pleased.
The quality of code we developed in pairs was *easily* heads and shoulders above code we wrote by ourselves.
In order to get a particular peice of code working, I went home one night, and from 11pm to 2am, hacked out some beautiful code that we needed. It was just one module. And we needed it to get some other things done.
"I don't need tests for this." I said to myself. "The other modules that depend on this will test it just fine! And besides, it works! See! I don't need all that extra stuff. That makes me so inefficient. My code usually works pretty good the first time through anyway. This will be OK for now."
"I don't need to pair program this." I also said. "This is really easy. I'll just slip it in there and noone will notice."
Yes, you know where this is going, don't you?
So I brought in the code, and I put it in the code base, and VOILA! It worked! It worked GREAT! See! I was right! And we continued on with our coding.
About a week later, we began noticing some new problems in a particular part of the code. A part which was wrapped up fairly closely with the code I had written in my midnight coding spree.
We began debugging the system. We wrote more tests for the modules that used my code. We ran it through the debugger. We poked it and prodded it. We peer reviewed it.
"Must be a rogue pointer!" We said. "The comm library must be too slow!" We said. "Damn that C++ string class! It's always acting strange." We said. "I'll bet this is a bug in the compiler!" We said.
We didn't write tests for my code because, well, afterall, it was working before, right? And besides, NOW, after the fact, it would take too long to write all those tests! We don't really need them, right?
Right?
Well, anyway, we spent 3 days trying to figure out this problem. We found lots of bugs, and we fixed them all, but none of them were the problem we were experiencing. Interestingly, as we worked the problem, it seemed like we kept following through on theories that lead no where. We went through a TON of rigamarole to find this elusive bug, that just wouldn't show itself, and was even hard to narrow down to a particular module.
Finally, I said "Forget this! We're spending all this time contorting ourselves to test my code that I have no unit tests for. I'm just going to write the tests and see what the damn thing is doing."
It took me about 2 hours to write the tests. And within 30 minutes of having the tests done, we found the bug.
Well, yes and no.
Was it in someone else's code?
Well, yes and no.
It was in a misunderstanding of how the two peices of code work together. But that doesn't really matter. The reasons we couldn't find the bug before were several:
In any case, in the end, I have learned my lesson. I admit, I *am* a cowboy coder at heart, but that's not what the team and the project needs most. I must restrain myself from coding against the rules *I* myself set! The resulting code is not *nearly* of the quality of the rest of the system, no matter how hard I try.