Develop custom functions more effectively using a simple test unit
An effective approach to writing code is to use automated tests. It's very simple to use the method when developing FileMaker custom functions. All it takes is a little table (you can use the provided sample) and about five minutes to add it to the project you develop.
Technorati tags: FileMaker, FileMaker 7, FileMaker 8, custom function, test unit.
- There must be a tool to run tests automatically.
- Tests must be written before the code they are supposed to test.
- The code is being written until all tests pass.
Let me show you how simple it is to make such an automated tester for FileMaker custom functions and then I'll amplify why the methodology turns out to be really effective. As I said, I already have a sample tester, but if this approach is new to you, you'd better follow the process step by step.
The simplest possible tester
You need a single test table; I suggest putting it in a separate file that can be reused among all the applications you develop. The table requires the following fields:Test, Result; both are text. The Test stores a FileMaker formula that evaluates to an empty value, if the test pass, and to a non-empty value, if it doesn't.
Assume you want to write a function Years( date 1, date 2 ) that must return a number of years between two dates. How you're going to test it works?
Of course, it must really provide the basic functionality: given a date, say, year an a half ago, it must return 1; given a date a couple of months ago it must return 0. Since you probably won't write a special handler for every possible date, it's sufficient to test only “frontiers”. Type the following text in the Test field:
today =
Get( CurrentDate ),
one year ago =
Date( Month( today ), Day( today ), Year( today ) - 1 );
almost one year ago =
one year ago + 1 ];
Case( Years( one year ago, today ) ≠ 1, "Error" ) &
Case( Years( almost one year ago, today ) ≠ 0, "Error" ) )
Now make a button to set the Result field to
Now with just a single click of a button you can run this simple test for your function: if the result is empty, the function works, if not, something is wrong and you should check the function code.
So why it's effective?
- Automated tests require very little additional effort to be run. Here you have to just press a button to run a test or all tests at once. This means you can test the code at almost every corner and always know whether it's solid or weak. Basically as a new custom function is added or another one is changed, you can run all the tests again to see whether or not the new code has integrated seamlessly.
- If you write tests before code, they serve as working specifications, and such specifications by their nature are more correct, elaborate and up-to-date than, say, paper ones. For an example of such a specification see the description of the actual test of the Years() function below.
- As soon as you have a test you're to pass, it works as a clear goal to you, so you're less likely to waste time inventing code more complex than it needs to be.
- You can easily share the file among different FileMaker applications and though you cannot copy functions yet, you can reuse tests for them.
The sample tester
The actual tester isn't that geeky as it may seem from the concise description above. It has additional “name” field, form, list and help screens, a few helper buttons and a couple of icons to better indicate results.
I also prefer to write tests using a special test function Assert Equals( actual value, expected value ) (described elsewhere) that makes the test specification clearer. (Note that this function has to be copied into the file you're testing.) For example, the actual test for the Years() function was the following:
This test was written before the I started coding the function and as you can see it's both quite readable as a specification and not bad as an actual test (though I already see it can be enhanced).
Adding the tester to your application
To add the unit to your files:
- Add a reference to the “Test” table in this file and name the table occurrence “Test”.
- Add a layout for the new table occurrence and name it “Test: Form”. The name is case-sensitive.
- Add yet another layout for the same table occurrence and name it “Test: List” (also case-sensitive). Make the layout viewed as list and set the size of layout parts:
header: 26 pixels;
body: 16 pixels;
trailing grand summary: 16 pixels;
footer: 16 pixels. - Optionally make yet another “Test: Help” layout.
- Copy the form layout from this file and paste it to the new layout in your file.
- Copy the list layout from this file and paste it to the new layout layout in your file.
- If you’ve made “Test: Help”, copy the layout as well.
- Optionally paint layout parts to your taste.
- You’re done (except functions themselves, of course; you might want to copy at least the
Assert Equals()function).
This instruction is repeated in the file itself, by the way. If you've done everything correctly, all buttons should work just fine.

Thank you very much, Mikhail. This is brilliant stuff. Inspiring.
Posted by: Steven Rosser | May 09, 2006 at 01:32 PM
how did you type a tab character - I have been looking all over the web for this - did you hit a control sequence before you typed the tab button on the keyboard? I simply copied/pasted yours so you saved the day
Posted by: Etienne Bley | September 27, 2007 at 01:06 AM