My Journey into Test Driven Development

2008 February 02
by Paul Marcotte
If you wonder about Unit Testing and Test Driven Development, but are afraid of commitment, do yourself a favour, read Terrance Ryan's thoughts on "How to convince yourself to Unit Test". A couple of months ago, I made a commitment to start unit testing. I'll admit that it took a little while to wrap my head around the terminology and process. A good practice point for me was to run some of my first CFCs though Seth Petry-Johnson's var scope checker. When I discovered a plethora of un-scoped vars, I used the opportunity to write tests against the methods I was going to change. After only a few tests, I started to get this warm feeling of security. By the time my updates and tests were complete, I had a nice little suite that I could return to any time a change was required.Prior to unit testing, I would test changes like this by navigating to a page within my application (perhaps a few clicks), trigger the method (maybe a form post, or clicking a link to a list page) and observe the output. More often than not, I would forget to re-initialize the application to refresh the component in Coldspring. I would often use <cfdump /> and <cfabort /> and then remove or comment out that code if I got the expected result. For my most recent project, I set up some initial tests, but continued to debug through the front end. The project uses ColdSpring, ModelGlue and Transfer. After a few painful, wasteful debugging sessions (add and MG event and listener, add a controller method to set values, add Service method to return value to controller), I set up some tests and was able to diagnose and fix issues faster than my previous process. Suddenly, that feeling of security returned. And now that I'm a fair way into the project, I have, by degrees, come to embrace the "test first, test often" credo. It was a paradigm shift, but not polar extreme. If I thought that I always wrote error-free code, I wouldn't bother unit testing. Reality is, I'm going to have to debug something at some point and I can save headaches and perform variations of tests quicker by embracing TDD than sticking with front end <cfdump /> and <cfabort /> testing. While I don't consider myself a TDD guru, I am feeling more confident and dedicated to the process. Here are a few terms common to Unit Testing that you can expect learn when you get started. Test Suite - A collection of test cases. Often you'll find an example suite named "AllTests", Test Case - A collection of tests. A test is nothing more than a method that contains an assertion of a testable behaviour from your object. Test Fixture - within a test case, you'll have several test for the same class. A unit testing framework will provide a way to "prep" the environment for your tests with methods to setup and teardown the test environment. Using setup, you create a test fixture. Test Harness - A test harness is used to automate testing. I consider it an advanced topic, something to grow into when you're ready to try continuous integration. Assertion - Assertions are the heart of unit testing. They provide the means for defining an expected result from your test. With assertions, you typically test for a return type, or value. When I started testing, I would run a type test first then a value test second. I have since changed to testing "behaviour" by setting the test to either pass or fail with an expect type and value. Mock Object - A goal of unit testing is to test the methods of your objects in isolation. To achieve this end for objects that invoke methods on objects it depends on, it is essential that you "mock" the dependency. If you use CF8, you can achieve a high degree of isolation and control over you mocks, by using Brian Kotek's ColdMock. Even though there is a lot to absorb when it comes to learning Unit Testing and Test Driven Development, I've found the process very interesting and rewarding. If you're sitting on the fence when it comes to unit testing, take an evening to dive in. The water's not too deep and you may come out feeling refreshed.