Fraction Jackson

I was getting a strange smearing effect when I tried to scroll in the main view of my application’s window.

I knew my content-drawing routines were being invoked correctly. I knew that the effect seemed to be happening somewhere in the depths of Cocoa, not in my code. But that’s all I knew.

Turns out, it’s because I was setting my view frames to fractional values (they’re floats, after all), but my content engine was still drawing things per integer coordinates.

This is the kind of thing that unit testing won’t help.

My goal was “make resizing the window and then scrolling through the main view work.” Can’t write a test for that because “work” means “look right,” and you can’t test for that when you don’t know how to make it look right yet.

It’s one part experimenting and one part perseverance and one part lightbulb going off after things go wrong.

And I find myself working through these kinds of issues a lot.

Anyone who says “Always write your tests first” can stick that in their pipe and smoke it.

2 comments

  1. Daniel Jalkut

    I’m not too expert with tests, but it seems like as often as not, tests get written after a bug has been found by other means. A major part of the “always test first” philosophy seeems compatible with this scenario. So before you fixed this issue you were supposed to write a test with a comment that says “blahdy blah view must always be integral because of limitations in our content engine,” before ensuring that the view’s dimensions are in fact integral.

    But ! you make a really good point that tests just can’t replace human observation. There’ s no “looksScrewy” category on NSView 🙂

  2. Andrew Pontious

    That’s the thing. *All* the books — and everyone I’ve talked to about it — say that you should always write the tests first: before writing any code at all. It’s “test-driven.” Writing the tests after you’ve written the code is “doing it wrong.”

    I though the Legacy Code book might demonstrate a way to apply this even to UI code. By using extreme measures if necessary to segregate out the logic from the dependencies, which in this case means all of Cocoa.

    But it doesn’t always work, and I’d like to make sure that’s part of the debate.