|Think about Loose Coupling|
As some of you may know, I've recently been exposed to the joys of testing. What you may not know is the experiences that I have had and what has finally converted me from a supporter of testing to someone who actively enjoys it.
Recently, a client asked us to make some changes to a Web site that required me to redesign part of the database. Part of my proposal was to spend time developing a test suite to cover those areas that would be affected. I started out by write a few small tests for a security object that I create.
That validate() method was the subject of my fourth test. As it turns out, I was getting data back when I wasn't expecting any. Oddly, this code has been running in production for well over a year with only one known bug, and this was an intermittant one that we could never track down. Since all this bug did was force people to log back in and it did not happen often enough to irritate our clients, it was given a low priority. What's worse, since I could never replicate the bug, I couldn't find it.
The fourth test that I wrote, after spending a whopping 5 minutes on this, found the bug. I was astonished. I deliberately chose the most stable module and instantly found a bug that I had never been able to track down. Hooray for testing!
As things went further, I tested the following function:
The code worked perfectly and didn't require any changes. However, as I started adding to my test suite, that code started failing for no apparent reason. As it turns out, because the Web is essentially stateless and since we were running this under ISAPI, we would typically only have one method call of this type per script invocation. When trying to run sequentially run several of these types of methods, an error on a previous method call that shouldn't affect this one caused it to fail, because I had never bothered to clear the error!
We hope to eventually port this to mod_perl, but if I tried to run this code under mod_perl with persistant objects, this would have caused massive failures. Hooray for testing again!
If this wasn't enough humiliation for me (I wrote much of this code), I discovered that tests for similar functions were often significantly different in structure -- I had inconsistent APIs. Had I known about testing when I wrote this and started with "test first" methodology, this never would have happened.
I now enjoy testing. Being able to say "my tests pass", as opposed to "gosh, I think it works", is a great feeling. I'm finding bugs I never knew were there, discovering API issues that I had never known about, and when code is hard to test, I realize that I have a design problem. Pure pleasure :)
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.