views:

74

answers:

3

For example, I have a piece of code that's generating a SQL*Loader control file from this template (using Python):

template = """
LOAD DATA
INFILE '%(file_path)s'
APPEND
INTO TABLE %(table_name)s
FIELDS TERMINATED BY "%(delimiter)"
OPTIONALLY ENCLOSED BY ""
(\n%(column_specifications)s\n)
"""

There are only two ways that I can think of to unit test this:

  1. Come up with inputs, figure out what the output should look like, then assert that the output is equal to that.
  2. Test that certain strings that should be in the file are in the file.

To me, these tests represent two different extremes. The first technique seems very fragile because I have to update the test if I do so much as change the whitespace. The second technique seems almost useless because it doesn't really test that text is going in the right place. Is there any kind of happy medium here that will keep my tests simple?

+1  A: 

Personally I think I'd be happy with Option#1 if the probability of someone changing this once it is working is low.

However if the whitespace thing irks you, you could always test from the consumer's point of view. It seems you're building a SQL query like thing here, so run it against a test DB with a test input file and verify the record count (or contents) matches the expected value.

Gishu
That wouldn't be a unit test though. :-)
Jason Baker
It wouldn't be a fast unit test.. but when you're writing code that generates images, files, etc.. the tests tend to lean towards the 'golden file'/reference file approach. How about running the output string/file contents against a command line diff tool that ignores whitespace
Gishu
+1  A: 

If you want to test that the templating works, #1. It's easiest to write and accurate. If you find that it is brittle, you can rewrite quickly as #2 (but there's no need to do that up front).

If you want to test the SQL, you really do need something beyond a unit test with a simplified db fixture and actually execute the SQL. It'll be slower than the unit test, but probably not particularly slow.

ndp
+1  A: 

I'd like to submit that you actually shouldn't write this test at all.

In my experience unit testing is about ensuring that the program actually does the things it should. Unless you actually wrote the templating code, you shouldn't have to test whether templating behaves correctly or not. Instead, ensure that the values going in are the proper ones, and also test that the right data gets properly loaded in the DB. After all that's the end goal of your code, not to produce the appropriate SQL string.

Tekahera