I’ve been diving into OCaml recently and I’m using my usual diving board. Whenever I want to learn another programming language, the first thing that I write is an xUnit-style testing framework.

I don’t do it just because I love testing frameworks, although that’s reason enough, I guess – writing one makes learning and working in a new language much more enjoyable. No, I do it because implementing xUnit forces you into the nooks and crannies of a language early. The first thing that you do is look for reflection, exceptions, and object structuring. Once you’ve used those parts in a language, you may not know the best way to do things yet, but you can survive.

So, here's the core of my first-attempt OCaml xUnit – the test_case class:

class virtual test_case test_name = object(self) method set_up = () method tear_down = () method virtual run_test : test_result -> unit method run result = result#test_started; self#set_up; try self#run_test result with TestFailure message -> result#add_failure test_name message; self#tear_down end;;

The run method contains a straightforward implementation of the template method design pattern. In OCaml, virtual means abstract. The run_test method is implemented in subclasses of test_case . Any exceptions that are thrown in a test are caught and passed to an instance of a class named test_result .

As it stands, this little xUnit works. It's functional, but it isn't really functional. In OCaml, you'd expect to see some functional idioms in use, but it's hard to see where they should be used. In xUnit tests have state. They call set_up to create it, and tear_down to get rid of it. How do you handle state in a functional way?

The typical answer in functional programming is to parameterize. Imagine that we don't have classes and we want to do everything that test_case run does. We'd end up with a function that looks something like this:

let run_test setup test_function tear_down result =

set_up;

try test_function result with

TestFailure message ->

add_failure result message;

tear_down

Nice, but look at all of those parameters! Makes you wish for objects again, doesn't it?

Well, not so fast. One of the cooler things you can do in functional languages is partial application. You can create a function that is defined as the application of another function to some subset of its arguments. So, if I want to have a set of tests that use the same setup and teardown, I can define a new function like this:

let xpath_test = run_test xpath_setup xpath_teardown

If you remember from above, run_test takes four arguments: set_up , tear_down , test_function , and result . What we've done now is bind xpath_test so that it uses xpath_setup and xpath_teardown any time that it is called. However, you still have to pass the other two arguments ( test_function and result ):

xpath_test a_test_function a_result

So, really, you don't need objects for template method-like work in a functional programming language. But, there is one little problem: state. When you're working in an object, you have shared state among your functions by default. When you working with functions alone, you have to pass state.

Here's how Ounit (a much more functional xUnit ported from Haskell) solves the problem:

let bracket set_up f tear_down () =

let fixture = set_up () in

try

f fixture;

tear_down fixture

with e ->

tear_down fixture;

raise e

The bracket function assumes that set_up will return a fixture of some sort. It also assumes that the test function and tear_down will accept the fixture. It looks a little convoluted, but I suspect that template method looks convoluted to many people also.

I suspect that over time I'll start to see functional solutions from the very beginning, but it's nice to see that the path toward more functional style isn't very rocky.