Sunday, December 21, 2008

Unit test the class

Travis Griggs comes to the conclusion that unit test objects should map 1:1 to classes under test.

I agree.

In fact, I would go a bit further: tests should be an integral part of a class. While this helps avoid negative outcomes such as parallel class hierarchies or having code and tests diverge, it more importantly simplifies the test/code relationship and drives home the point that code is incomplete without its tests.

While I was working with JUnit on a reasonably large Java system, both finding a good place for a particular test and finding the tests for a specific class became quite burdensome after a while.

For this reason MPWTest simply asks classes to test themselves. Furthermore, only frameworks are tested, so the test tool simply loads each framework to test, enumerates the classes within that particular framework and then runs the tests it finds. TestCases and TestSuites are implicitly created from this structure, removing most of the administrative burdens of unit testing, and also any explicit dependence of the tests on the testing framework.

Having no dependencies on the testing framework makes it easier to ship tests in production code without having to also ship the testing framework. While this may sound odd at first, it avoids potential issues with code compiled for testing being different than code destined to be shipped, and further reinforces the idea that tests are an integral part of each class, rather than an optional add-on.

Sunday, October 12, 2008

Binary XML

Jimmy Zhang hits the nail on the head when he notes that parsing ASCII text is not the primary problem in XML performance, object allocation is. I was surprised by the same finding when I started working on Objective-XML around a decade ago.

Sean McGrath claims that Binary XML solves the wrong problem.

Yes and no: it doesn't help much with existing structures and parsing methods, but with the right methods, it can be extremely helpful!

Also: " weird is it that we have not moved on from the DOM and SAX in terms of "standard" APIs for XML processing?"

Sunday, August 10, 2008

Code is not an asset

Michael Feathers wonders how to go beyond technical debt. I have been wondering about this for some time, and I think the answer is to account for code as a liability, not an asset.

The functionality that the code has, the value it delivers is an asset, but the code itself is a liability. This easily explains how refactoring and removing code add value, as long as functionality is preserved.

Sunday, April 20, 2008

Higher Order Messaging backgrounded

Piers Cawley talks about RSpec's use of HOM:
It is, however, encouraging to see initiatives like Rspec which, through judicious use of higher order messages enables a much more fluent environment for writing tests:
I think that's the first time I've seen HOM used to explain something else, rather than being the object of attention itself. So HOM is starting to be seen as simply a part of the computing landscape, at least by some. Cool. HOM was never conceived of as an interesting thing by itself but rather as a (meta-)building block for building more expressive computational forms. RSpec looks exactly like one of those cool things HOM enables that I would never have come up with myself. I look forward to seeing more.

Not just high performance Objective-C

Addendum to my article on implementing a high performance Postscript interpreter in Objective-C: not just is performance better, so is accuracy. Despite the fact that we are optimizing the heck out of the Objective-C objects we are using, they still give us encapsulation and polymorphism, allowing us to choose arbitrary representations. For example, most Postscript interpreters use a fixed-size value object (polymorphic in a C-union type of way) that constraints floating point precision to 32 bits. With Objective-C, we have no such constraints, so EGOS floats are actually 64 bit doubles, so running the modified benchmark below in PostView doesn't just yield the result 75% faster than Preview, it also produces it with 7 orders of magnitude less error. Not that that is necessarily important in Postscript, but it is a pleasant side effect and shows the power of combining performance with abstraction.
  1000 0 1 10000000 { pop 0.0001 sub  } bind for
  exch usertime exch sub dup ==
  20 20 moveto /Times-Roman 24 selectfont
  100 string cvs show ( ms) show ( error:  ) show 
  1000.0 div 100.0 mul abs  100 string cvs show ( %) show