Saturday, February 7, 2009

Logo development update: Test driven development and Logo Lexer

Test driven development is relatively new to me in the sense that, while I've known about it for some years, I've never used it in any non trivial project. This deficiency is something that I regret.

To be more accurate, not using test driven development is something I feel that I should regret, but deep down inside I do not. Most working developers understand things need to get done under a certain deadline. To state the obvious, certain development methods take longer than others to initially deliver a result. If the final product is something with loose requirements or requirements that are hard to test, test driven development is probably too expensive in terms of the time it will take to push out a change. However if you have a tightly defined spec with well defined requirements, then test driven development may work for you.

Note that while I do not think test driven development is the bees knees, I do believe well defined tests are essential. Most projects are better for having rigorous tests, but you have to think carefully about the way you place writing tests into your development process. For some projects, it's better to write tests before you've written a line of code, for some it's better after you've written the entire thing, and then there's all that stuff in between. Who really cares, it's all very domain specific, and it's been written about before and written better. We're done with this topic and we're moving to part two:

Logo development will be test driven. The test driven development model appeals to this project since ucblogo is a (mostly) well defined language whose core concepts rarely change over time. It's important to write the tests before writing the code since the tests will essentially write the spec for interpreter implementation.

So far I've written several tests for the logo lexer. Each test is separated into two files: a test file with a sample logo program, and an expected results file with the logo lists written as strings. Each test file will be read and executed by a junit test in the lexer module and the output will be compared to the correspond expected file.

Here is the sample test and expected file:

sample.test
;; a simple print statement
print "simple

sample.expected
[print quoted simple]


As per usual, let me first state why this method of testing is bad (and by association why it makes me a bad developer):

This approach sucks because it separates the core part of the test from code itself and makes it more difficult for me to read my test files . Now I have to create a separate conf file to hold path variables that java doesn't know about natively since it's not embedded in the code. This conf file makes the build process more complicated, since I now need to include this file if I'm testing, but not include it if I'm running the app as normal since I don't want the dependencies in the final application.

So why did I choose this method to develop the Lexer tests?

This approach is nice because it separates the core part of the test from the code itself and allows me to switch the code base I will be using if I need to. Since this project is in its early stage, if I decide it would be better to write the interpreter in say, actionscript or C#, I could switch without losing everything I wrote. Java is a nice platform and all, but in reality, it's not an ideal language for this kind of development. If I find out there's a better multi-platform (in terms of both browser and OS) language for this kind of work, then I want to be able to quickly and painlessly jump ship.

No comments: