Unit testing is not a substitute for static typing.
Users of of dynamic languages such as Python, Perl and PHP, are often faced with the additional task of ensuring that type-related errors do not occur in their programs at runtime. Some authors [1, 2] claim that this can be done effectively by the use of extensive automated unit tests. However, practice has shown this to just not be the case.
Automated unit tests have their place. But they should not be used to check for typing errors. Software typechecking is a mechanical task, and thus is just the sort of thing that should be delegated to a computer. And this has been done for quite some time now, in the form of statically typed programming languages. Users of such languages, such as Haskell, OCaml and Standard ML are freed from having to worry about such menial and tedious tasks. The rigorous nature of the compilers for those languages often do a far better job at checking for type errors than a human typically could.
Proponents of dynamic languages often suggest that such languages bring an increase in developer productivity. But if the developer ends up spending so much time writing unit tests to perform a task that is readily done automatically, we really don’t see the supposed productivity boost. And if the developer doesn’t write such unit tests, the chances of a runtime type error crashing the application are far greater. So now the developer must choose between his or her software crashing and disrupting the users’ work, or spending a lot of time to write unit tests. None of the choices are reasonable, let alone optimal.
Static typing is clearly the answer. Not only does the compiler take care of the tedious task of type checking, but any inconsistencies are detected at compile-time, rather than runtime. Thus it is the developer who deals with such errors, rather than the user. Furthermore, the developer is now freed up from writing automated unit tests to check for type errors, and can instead put more emphasis on unit testing the functionality and integration of his or her code. Clearly, static typing is the only sensible, and the most efficient, route to take.
February 12th, 2008 at 12:14 am
Can you define just what is meant by “type-related error”?
I can’t recall the last time I had Ruby code break because I tried to act on an object of the “wrong” type. I have unit tests, but nothing that specifically attempts to verify object types.
I write tests that verify behavior. The typing seems to take care of itself. What am I missing?
February 12th, 2008 at 3:58 am
All the static typing in the world won’t save you if you have a logic error.
The vast, vast majority of bugs I’ve hit, in both static and dynamic languages, are logic errors.
Therefore, even statically typed languages require heavy unit testing to reduce bugs.
If you’re going to have unit testing anyway, why perform checks at both compile- and run-time?
February 17th, 2008 at 5:32 pm
[…] days back I wrote about how unit testing is not a substitute for static typing. A comment posted to that article by James asked for more clarification regarding what I was […]