A colleague recently complained to me that I'm forcing him to write a unittest without a good reason. He had written a small method which he told me that there's almost no way of breaking, it's so trivial that it doesn't need a test.
The code in question was written in Python and looked like this:
from some.module import Settings
class Object(Base): def is_fluff(self): return self.state == Settings.STATE_FLUFF
In his change he added the is_fluff method, which wasn't previously defined (but self.state) was.
I told him that there are a actually possible to break the method in a number of different ways:
- by changing the method name
- by changing the attribute name
- by changing the constant name
- by changing the constants module name
- by changing the type of the attribute
- by changing the type of the constant
- by changing the value of the constant
- by changing the operator
- by changing the function prototype
- by removing the return keyword
- by subclassing the object and overriding the method
This is not a complete list since Python is a very dynamic language. You can change the behavior of objects in various interesting ways. Overriding attribute lookup, the comparision operator, class creation, method invocation etc etc etc
So by writing a very simple test like this:
o = Object() o.state = Settings.STATE_KLARKE assert not o.is_fluff() o.state = Settings.STATE_FLUFF assert o.is_fluff()
The moral of the story is that we're actually testing a lot more than just a simple comparision in a dynamic language like Python where the compilation process is very simple.
This is not an attack on dynamic languages like Python. A language which does extensive type checking at compilation time is likely to catch a few of the possible errors I listed, but not all of them. The most dangerous one is changing the value of the constant, no tool in the world can help you catch that. (assuming our object is going to live longer than the time of our program, eg the values are going to be saved in a database)
You'll need to write a unittest for your program regardless of the language you choosed to implement it in. Python makes it easy to write and maintain code and since unittests should be written anyway it's on the winning side ;-)