Testing is, obviously, crucial to the software development process. I am pretty sure that if I wrote a hundred lines of code without running the code even once, it probably wouldn’t do what it’s supposed to do, if it even worked at all without crashing.
So testing, in general doesn’t suck. It’s unit testing that sucks. As you probably know, otherwise you wouldn’t be reading this article, unit testing is the concept that you can write additional code to test your code. Yes, this is something only a hardcore geeky programmer could love: writing code that has no purpose except to run other code. The theory is that your unit tests can be so thorough, testing every single unit of code, that the result is a rock-solid bug-free application.
If only it actually worked as well as the theory! In practice, unit testing is a monumental waste of time. Even worse than a waste of time, the result is often lower quality software that’s harder to maintain. The problems with unit testing are as follows:
(1) It’s impossible to test all possible permutations. You might have to write an infinite number of unit tests. Unit testing advocates may point out “well, it’s better to unit test what you can.” I don’t think so. Time wasted on unit testing could instead be spent by the skilled programmer to improve the quality of his riskier code. The skilled programmer has an intuitive sense of what parts of his code are likely to cause problems.
(2) Whatever you figure out needs to be tested is stuff you would code to work correctly anyway. The bugs that have always showed up in the applications I’ve worked with are unanticipated combinations of user actions or circumstances.
(3) The most important part of the application is the user interface. That’s the part of the program that the user interacts with—programs, after all, are meant to be used by people and not by unit tests. The interface tends to be the most prone to bugs, and it’s impossible to test via unit testing because using the interface the way a real person would use it is just outside the realm of what you can code.
(4) Writing unit tests is incredibly boring. Unit testing advocates might respond, “well that’s too bad, it’s necessary.” But it’s not necessary, and forcing your programming staff to do really boring tasks results in sapping their motivation thus lowering their productivity.
(5) The biggest problem I have with unit testing is its reliance on design patterns concepts. The standard test driven software project requires you to create various application “layers,” with each layer being an interface that receives other interfaces. This allows you to create mock objects that you can substitute for real objects, allowing you to test a small piece of code in isolation from the rest of the project. In order to make your application unit testable, you must make the application a lot more complicated, and complexity introduces errors. Ironically, the unit tests, if they discover errors, are probably only discovering errors that wouldn’t have happened in the first place if you weren’t doing test driven development with overly complicated design patterns.
I know that a lot of people will remain unconvinced. They will think, “I have worked on projects with unit testing, and it has found so many bugs!” But as I said in point five above, the bugs found are often bugs that wouldn’t have been there in the first place were it not for the unit tests. And unit testing generally only finds the big bugs which would have been obvious soon enough when you ran the program.
There is also the theory that unit testing ensures that, when you change some code, it doesn’t break other code. Well that’s only true if it breaks something in a way anticipated by the unit test. But you have to ask yourself, why is your project architected in such a way that it’s so susceptible to a small code change in one place breaking code elsewhere? No, it’s not because of “tight coupling” or failure to follow object oriented design patterns. It’s because of bad planning, and bad developers who confuse unit testing with quality coding. It’s because too many developers are working on the same parts of the project. Too many programmers spoil the code just as surely as too many cooks spoil the broth. The only way to create a quality big project is to divide it up into independent small projects.