I hosted a JUnit Factory presentation a few days ago (you can watch it online if you missed it first time around) and spent a fair amount of time talking about the Triangle sample in the JUnit Factory demo.
The Triangle sample is my favorite because it's a classic in the testing literature. Mike Myers used it in The Art of Software Testing in 1979 as an example of a simple piece of code that requires a lot of tests. He challenged his readers to write a test plan for a program that
...reads three integer values from a card. The three values are interpreted as representing the lengths of the sides of a triangle. The program prints a message that states whether the triangle is scalene, isosceles or equilateral.
Myers goes on to describe the 14 tests that are required to adequately test such a triangle.
Bob Binder takes up the triangular baton in the introduction of his Testing Object-Oriented Systems (I have Alberto's autographed copy in front of me). Binder describes an elaborate system of objects that does essentially the same thing. He claims to need 65 tests to test his triangle class - which, you should note, does not have the same requirements as Myers' original.
Fast-forward to this century and Kent Beck claims to need only 6 for his TDD'd solution. I can't find Beck's implementation or his tests - but I did find a fascinating discussion about it on usenet (Google for Triangle, Beck, Binder) involving both Kent Beck and Bob Binder.
Anyway, so that's why I chose the triangle example for JUnit Factory (JUF). I was delighted to see another discussion of triangle testing after Elizabeth Hendrickson blogged about a JavaScript implementation. The most fascinating thing for me is watching the progression in language design and programming aesthetics that makes whole classes of bug impossible. Myers' tests include one for non-numeric inputs; Binder's check for a missing input - neither of these bugs is possible with the Java implementation - but JavaScript opens up all of these possibilities plus a whole bugs' nest more.
JUF comes up with 25 tests (again, an exact comparison to the other suites is not possible because the requirements are slightly different) which, to my inexpert eye is close to adequate. They make a nice complement to any tests you may have written manually as programmers (even test-infected programmers) are notorious for only testing the happy path...
public void testConstructorThrowsIllegalArgumentException5() throws Throwable {
try {
new Triangle(100, 1, 1);
fail("Expected IllegalArgumentException to be thrown");
} catch (IllegalArgumentException ex) {
assertEquals("ex.getMessage()", "Not a triangle", ex.getMessage());
assertThrownBy(Triangle.class, ex);
}
}
...or for overlooking requirements...
public void testIsIsosceles2() throws Throwable {
boolean result = new Triangle(36, 36, 36).isIsosceles();
assertFalse("result", result);
}
What do you think? Could you test a triangle better than JUnit Factory?. Let us know!
Posted by Kevin Lawrence at April 6, 2007 02:47 PM
TrackBack URL for this entry:
I'll award a years supply of free tests to the first Englishman who can tell me what the title refers to :-)
[Sorry. Scotsmen and Welshmen not eligible]
Posted by: Kevin Lawrence on April 6, 2007 02:57 PM
I asked Mr Confectioner and he told me that it refers to Toblerone and now I have that advert jingle stuck in my head THANK YOU VERY MUCH
I am confused as to why Scots and Welsh aren't eligible though :-S
Posted by: philk on April 7, 2007 06:32 AM
Oh! Mr Confectioner please!
Posted by: Kevin Lawrence on April 9, 2007 08:12 PM