Ads by The Lounge
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.
I was skeptical about the benefits of Unit Testing, like many developers I work with. I work with a lot of development teams as a teacher and trainer. I’d seen some teams benefit, but others got nothing but headaches. My latest project has me convinced that rigorous automated Unit Testing is a software development best practice. It saves time, and enhances your ability to create great software. Let me share my experiences on a large ongoing project. It convinced me, and I think it will convince you too. We introduced unit testing on my current large project, a change from my previous project. Comparing the progress of the two projects has sold me on its benefits. We are several months in and well past the point that I can keep all but the high level architecture in my head at one point in time. The typical scenario on past projects was that I would write some amount of code, one to fifteen lines of code and run the project. I have often included a button on forms that would fill out all of the fields with the minimum required data to speed up the manual testing process. Right here was one issue – I was putting testing code into the production application. The testing process consisted of poking at the application and trying to break things. I would store up two or three issues before trying to run because this process was so painful. Of course, this took ages because I would find something wrong and would have to quit testing, fix the code and rerun. I had no idea how broad changes would be if I fixed a given component. The further down in the architecture, like a database helper class, the scarier this became. Even to test the particular UI bit that I knew that it affected, I would have to log into the app, navigate to the page with the error and then fill out the form and so on. Since I couldn’t possibly know everywhere that was affected this could take a lot of time and it still wouldn’t be right.Somewhere in here, I would have flash backs to my mainframe days where you’d write code, hand walk it, submit the 10 new lines of code to the compiler and wait. You’d have the results of your compile printed out 2-4 hours later, depending on whether or not the big iron was under load. The next step was to correct the spelling because none of the tools had IntelliSense and start the whole process over again. Throw in a lunch and that was your whole day. You had accomplished the task of compiling 10 new lines of code. The next day, you’d get to test it and then fix it again.These practices impede forward progress on a project so that I can either laugh or cry. I stay sane by realizing first that I’m not, by any stretch of the imagination, telling war stories that you haven’t personally felt as well and second, there is a better way now. My current project is much different because of testing, testing and more testing. I know exactly what I have and haven’t broken a mere matter of seconds after making the change. Let’s start by talking about the database helper class scenario. I make a change to one of the methods in the database helper class. Now, rather than running and guessing as to what’s changed, fixed or broken, I’ve got automated tests that test that particular method in several different ways directly. I pass in several types of good data and bad data. If it stopped here, that would be good, but it still might have broken something else that I didn’t realize. In addition, I’ve got automated tests for the data classes that use the utility classes. And I’ve got automated tests for the middleware that uses those data classes. And I’ve got automated tests for the ASP.NET UI. And the best part is that all of the backend and middleware tests run in about thirty seconds. The ASP.NET code actually makes the HTTP calls and renders the HTML, parses it and so on so they take a touch longer. Even running all of the tests takes just a couple of minutes. At that point, I can feel free to move on and write more code without that same knot in my stomach that I’ve broken something that I didn’t know about. I’m not spending time repeating myself and typing in the same meaningless test input into the UI over and over. I am using the computer to do that for me. It makes for more repeatable, consistent tests that actually get executed. Now, that being said, I don’t believe that the tests that I’m writing can replace the testing that a business analyst, the user or a quality assurance team does. When the tests that I run pass, that means that the code does what I meant for it to do. There are a number of limitations with this. First, it could be that I forgot a possible scenario. Second, the code that does what I meant for it to do might not do what the user or business analyst meant for it to do. If we have communicated well, it will be close but it’s possible that there a misunderstanding which will have lead me down the wrong path. I still haven’t bought into all of the TDD philosophy. I still don’t write my tests before I write the code. I just haven’t been able to get my head around that concept yet. I have trouble thinking about all of the ways that the code is going to be used and writing tests and then writing the code. I’m thinking that I will make that transition at some point for some tests. I’ve been thinking that I should take my use cases and start from there writing tests. In future posts, I’ll talk about my thought process here. One of the keys to a good unit testing experience is having the proper tools. I’ve put together what I think is a good toolset, at least for ASP.NET, that is able to test the vast majority of what I need to test. I'll talk about this toolset and how you can get started on unit testing yourself in future posts.