16 Aug 2006 jdahlin   » (Master)

Testing a dynamic language

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:

  1. by changing the method name
  2. by changing the attribute name
  3. by changing the constant name
  4. by changing the constants module name
  5. by changing the type of the attribute
  6. by changing the type of the constant
  7. by changing the value of the constant
  8. by changing the operator
  9. by changing the function prototype
  10. by removing the return keyword
  11. 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 ;-)

Latest blog entries     Older blog entries

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!