The Shape of Everything
A website mostly about Mac stuff, written by Gus Mueller
» Acorn
» Twitter
» Maybe Pizza?
» Code
» Archive
July 27, 2010

I've been writing more tests for Acorn lately, and it's been kind of fun since I've been coding them up using my little Cocoa/JavaScript language, JSTalk.

Acorn has traditionally had all of its tests coded up in Objective-C, and run via part of the build process or by a special Debug menu that shows up in my dev builds. (I don't use the built in testing framework that Xcode supplies, since it doesn't work very well with Acorn. So I wrote my own, which is actually pretty easy.)

It's all well and good, but the problem I run into is that to fix a single test, I have to run through all the other tests just to get to my problematic one, which can be a bit annoying if I have a breakpoint set on a commonly used method. So to get around this problem I've been writing up single tests as a JSTalk script:

// standard include stuff for the tests
[jstalk include:"acornsetup.jstalk"];

var testFileName = "floodfillend2.png";
var doc          = [acorn open:PXTestImageFolder + "/floodfillstart.png"];
var win          = [doc windowController];

[[acorn toolPalette] setFrontColor:[NSColor redColor]];

PXWithUndo(doc, function() {
    [[win canvas] placeBezierRectOnMask:NSMakeRect(0, 50, 30, 30)];
});

PXWithUndo(doc, function() {
    [[doc currentLayer] floodFillAtPoint:NSMakePoint(8, 62)];
});

PXCompare(doc, testFileName, 0, true);

The first line includes some standard bits that the test scripts can use such as finding the PXTestImageFolder location, assigning the variable "acorn" to the app (var acorn = [JSTalk application:"Acorn"];), as well as some other things. The function PXWithUndo is kind of interesting:

function PXWithUndo(doc, f) {
    [[doc undoManager] setGroupsByEvent:false];
    [[doc undoManager] beginUndoGrouping];
    f();
    [[doc undoManager] endUndoGrouping];
    [[doc undoManager] setGroupsByEvent:true];
}

The english version of the script goes something like this:

  • open up file "floodfillstart.png"
  • put a selection on the canvas
  • tell the current layer to perform a flood fill at a specific point
  • call PXCompare with some arguments, testing it against an image it should look like at this point.

The PXCompare function takes a document (which is the one we just worked with), a path to a file to compare it against, an int which is the tolerance to use when comparing the two images, and finally a bool which lets the function know wether or not to test our undo support. If the compare test fails, Acorn opens up the images and an alert box letting us know "hey something broke".

I've got a folder with a bunch of these tests, which all get run as part of Acorn's build script. If a test fails, then the build script stops everything and you get to hear me curse loudly.

So the moral of this story is automated testing is awesome and even if Xcode's testing framework doesn't suit you then you should probably investigate using something else. And why not check out JSTalk while you're at it? It's super easy, I promise!