Staying Fit With Learning Tests

December 28, 2004

For fun, and to tickle my brain, I'm exploring the machinery that makes FIT go. Oh, I know how to write FIT tests, but I'm curious as to what goes on under the hood when a test is run. And I want to take the opportunity to learn from Ward's coding style. His style is different from mine and that difference makes my brain hurt in the good kind of way. It pushes me outside of my comfort zone to that place where learning isn't inhibited by constraints. What I experience doesn't have to be right or wrong, it just is.

To apply what I learn, I'm writing a custom fixture that hooks into the FIT framework. I'm using a technique someone coined Learning Tests. It's easy. Given an API you want to use, start by writing tests that validate your expectations about the API. My expectations are usually wrong, but I end up learning something in the process. The collection of tests I ultimately write are a record of the things I learned along the way. When I forget how to use a particular method of the API, I can refer back to the learning tests as an example.

When I'm in learning mode, I start by writing a lot of tests that look like:

<SomeType> actual = object.method(someInput);
assertEquals(null, actual);

It's the "I dunno" test. OK, I might have a clue about what the actual return value should be, but I want the computer to tell me straight up what it is. In addition to being accurate, the computer is usually much faster than all my pondering. Running the test generally results in something like:

junit.framework.ComparisonFailure: expected: <null> but was: <actual result>

Stimulus, response. Aha! Then I change the test to:

<SomeType> actual = object.method(someInput);
assertEquals(<actual result>, actual);

Then I run the learning test again just to see green. Now I know that this particular sequence of method calls and inputs results in this particular output. And I've recorded that knowledge in a test. I can then apply what I've learned when using the API in production code. I have an example to draw from.

Wanna hear a secret? Sometimes I actually copy/paste the body of the learning test into a method of production code that has a failing test. That is, I'm literally transferring what I've learned into something usable by the application I'm building. Then I rewire the API inputs and outputs to suit the enclosing method. Finally, I run the failing test to validate if I've correctly applied my learning to the thing I'm building. In the case of FIT, I'm using my learning tests as examples of how to write a custom fixture.

I learn by doing. Learning Tests are one way I practice doing.

Read more posts in the blog archive »