Tuesday, July 7, 2009

Ighalsk - in which I discover StringIO

The suite of unit (more or less) tests that I run for Ighalsk currently takes about 11 seconds to run 281 tests (for the current version with Subversion revision number 58). This is not too bad, but I've read about projects running more than 1000 tests in less than 10 seconds, perhaps even less than 1 second. In particular, the suggestion is to avoid file accesses in unit tests (see for example Michael Feathers here).

When using Java, I think the idea is to accept an abstract Reader object as a parameter, which can be a FileReader object in the actual program, and can be mocked as a StringReader (or is it ByteArrayInputStream? so many choices!) in test code for speed. (On checking, I found that the example I was thinking of is actually for .NET ...)

I was planning to implement my own FileReader and StringReader objects in Python, but then I'd have to unit test those as well ... when, reading through the Python manual, I discovered a class called StringIO!

Its description begins, "This module implements a file-like class, StringIO, that reads and writes a string buffer (also known as memory files). See the description of file objects for operations ..." - which is exactly what I wanted!

I've started using this approach (mocking file objects using StringIO) in new classes, but I still need to switch to it for existing classes. In most cases, it should be a matter of opening a file and passing in the file object before calling a function instead of passing in a filename and opening the file inside the function, though this still means that there'll be at least one class somewhere that will still have to open some files ... but separating out this functionality should mean that file I/O only needs to happen in a small number of unit tests. Yet another treasure hidden away in the depths of the standard Python libraries!

No comments:

Post a Comment