Dear Twitpic Community – thank you for 4 winning automation software testing techniques the wonderful photos you have taken over the years. We have now placed Twitpic in an archived state. For certain types of code, unit testing works brilliantly, flows naturally, and significantly enhances the quality of the resulting code.
But for other types of code, writing unit tests consumes a huge amount of effort, doesn’t meaningfully aid design or reduce defects at all, and makes the codebase harder to work with by being a barrier to refactoring or enhancement. At one point I thought this observation was somehow controversial, but every other developer with whom I’ve discussed it already considered it self-evident that unit testing is sometimes very effective and sometimes just isn’t. So why am I writing this? TDD code-first process, then they’ve failed as a professional. I’m not satisfied with that view. How much does that code benefit from unit testing?
Consider: Why do you actually want a secondary system to help design or verify your code? Doesn’t your source code itself express the design and behaviour of your solution? If unit tests are a repetition of the same design, in what sense do they demonstrate the correctness of that design? For example, if you’re coding a system of business rules or parsing a complex hierarchical string format, there will be too many possible code paths to check at a glance.
For example, if you’re writing a method that gets the current date and the amount of free disk space, and then passes them both to a logging service, the source code listing says everything you need to say about that design. In summary, I’m arguing that the benefit of unit testing is correlated with the non-obviousness of the code under test. How much does it cost to unit test that code? As many have written, you can reduce the cost of maintaining unit tests by following certain best practises. After doing that, the remaining cost may be tiny or it may still be significant. In my experience, the remaining total cost of unit testing a certain code unit is very closely correlated with its number of dependencies on other code units. Writing tests in the first place: If a method has no dependencies and merely acts as a simple function of a single parameter, unit tests are just a list of examples of input points mapping to output points.
Maintenance: It’s well established that the more direct dependencies a code unit has, the more frequently it gets forced to change. You can easily see why: On any given day, each of those dependencies has some probability of changing its API or behaviour, forcing you to update your code and its unit tests. Note that these issues apply equally even if you’re using an IoC container and coding purely to interfaces. Typically this means self-contained algorithms for business rules or for things like sorting or parsing data. This cost-benefit argument goes strongly in favour of unit testing this code, because it’s cheap to do and highly beneficial.
Did not find what they wanted? Try here
This cost-benefit argument is in favour of not unit testing this code: it’s expensive to do and yields little practical benefit. This code is very expensive to write with unit tests, but too risky to write without. We needn’t worry about this code. In cost-benefit terms, it doesn’t matter whether you unit test it or not. NET MVC, the most general-purpose place to put your application logic is in your controllers. To avoid this, you can factor out independent bits of application logic into service classes and business logic into domain model classes. You can also split out cross-cutting concerns into ASP.
NET MVC filters, custom model binders, and custom action results. The more you do this, the better, clearer, and simpler your controllers become. Ultimately, the better you structure your controllers, the more they end up being trivial coordinators that manage interactions between other code units while having very little or no logic of their own. In other words, the better you structure your controllers, the more they move down towards the bottom-right corner of the preceding diagram, and the less it makes sense to unit test them.
My controllers aim to be just a meeting place for all the different APIs of my many services. This controller code is trivially readable, and links together multiple dependencies. In cost-benefit terms, I find I’m more productive not unit testing these and instead using the time saved to keep refactoring and writing integration tests. But, um, surely we don’t want less automated testing?
In case anyone is misinterpreting me, I’m not saying you shouldn’t do unit testing or TDD. I personally find I can deliver more business value per hour worked over the long term by using TDD only on the kinds of code for which it’s strong. The most obvious example is factoring application logic out of ASP. I’m increasingly becoming aware of the practical business value achieved through integration testing. For a web application, that usually means using some kind of browser automation tool such as Selenium RC or WatiN.
This is just a description of my experience so far. It’s OK if yours is different. Doesn’t your source code itself already express the design and behaviour of the solution? Journal entitled What is Software Design?
After reviewing the software development life cycle as I understood it, I concluded that the only software documentation that actually seems to satisfy the criteria of an engineering design is the source code listings. A programming language succeeds or fails to the extent that it lets us succinctly and accurately describe our intended software design to the compiler. So, reader, can and should unit tests replace source code as the truest expression of our designs? Steve Sanderson A web developer with a particular interest in building rich browser-based apps.