Tim Scott's Blog

January 10, 2010

ShouldIt Is ILMerged

Filed under: Programming, Test Driven Development, Unit Testing — Tim Scott @ 6:49 pm

ShouldIt is a library of fluent specification extensions that works with all of the popular testing frameworks. My goal with ShouldIt is to provide a robust set of testing extensions that I can drop in to any test project, and it just works.

So far ShouldIt has met that goal, well mostly. One small friction point is the need to reference four DLLs (not counting the testing framework itself) in my test projects. No more. I have added an automated build that ILMerges all the required assemblies. And to make it easy for others to adopt ShouldIt, the download page now has a single file download for each testing framework.

Advertisements

November 30, 2009

A Question Of Astonishment

Filed under: FluentHtml, Programming — Tim Scott @ 5:26 pm

Steve Michelotti recently found a very subtle bug in MvcContrib.FluentHtml.   It provides us with a rather interesting case of applying the Principle Of Least Astonishment (a.k.a. Rule Of Least Surprise).

It turns out that FluentHtml’s select helper lets the user express his intent vaguely.  Consider whether this test should pass:

[Test]
public void when_determining_selected_values_select_should_ignore_selected_method_if_any_options_are_marked_selected()
{
    var list = new List<SelectListItem>
    {
        new SelectListItem { Text = "Acura", Value = "1", Selected = true },
        new SelectListItem { Text = "BMW", Value = "2" },
    };

    var select = new Select("foo.Bar").Selected(2).Options(list);

    var optionNodes select.ToString().ShouldHaveHtmlNode("foo_Bar").ShouldHaveChildNodesCount(2);
    optionNodes[0].ShouldBeSelectedOption(1, "Acura");
    optionNodes[1].ShouldBeUnSelectedOption(2, "BMW");
}

See what we have done here? We have allowed the user to express which options should be selected in two, possibly contradictory ways. In the call to Options, the user has specified that Acura should be selected. In the call to Selected, she has specified that BMW should be selected. How should we interpret what she really wants?

The first path to consider is to change the API to remove the chance for vaugeness. In most cases this is highly preferable. In this case, however, the cat is already out of the bag so to speak. That is, changing the API in this way would be a big breaking change.  Furthermore, it is deliberate and I believe very useful that the API offers a lot of ways to specify select options.

That leaves us to invoke the Rule Of Least Surprise. When a user specifies vague intent, in the manner that we have described, I can see five reasonable outcomes:

  1. Selected items are only those expressed via Selected
  2. Selected items are only those expressed via Options
  3. Selected items are a union of those expressed via Selected and Options
  4. Selected items are only those expressed via Options or Selected, whichever is called last
  5. Selected items are only those expressed via Options unless none, then those expressed via Selected

I will reject #4 out of hand.  FluentHtml helpers are essentially builders.  And with builders, order should never be important.  #1 and #2 are the next to go.  I cannot think of a better argument for either, and so the choice would be arbitrary.  It’s a rather close call between #3 and #5, but I will choose #5.  Here is the thinking.   If the user has specified selected items within the options themselves, then calling Selected is clearly a mistake on his part and he should expect it to be ignored.  On the other hand, if he did not specify selected items within the options list, then he could reasonably expect the call to Selected to be honored.

Would you make a different choice?

September 29, 2009

The Tale Of The Tape

Filed under: Programming — Tim Scott @ 4:44 am

Joel Spolsky recently set off another flurry of discussion in the blogosphere with his post extolling the noble duct tape programmer.  Most of it was not too bad.  But what could have been a nice rant against architecture astronauts was ruined when he drew a false dichotomy between overwrought architecture and duct tape.

Which brings me to my story.

Just today I came across a charming little piece of duct tape. Here’s how I imagine it got there.  During construction of the system some tester reported a problem: “When I do [x] I get an ugly error, and I cannot complete the task.”  The job of fixing the error was quickly dispatched to a clever duct tape programmer who “solved” it equally quickly by wrapping about 100 lines of code in a try-catch block that swallows the exception.  Before you groan too loudly I should mention that this code has been in production for a year or more.  Does that prove that duct tape was the right tool?

Not so fast.  Back to what happened today.  A colleague and I spent about an hour scratching our heads over a failing acceptance test.  It turned out that this little piece of tape was masking a problem elsewhere in the code.  What should have taken five minutes to solve took two person hours.

Is it a good trade off?  Absolutely!  Um well, unless the business needs to change.  The thing is, it does need to change.  It needs to change a lot.  I will venture to say that all businesses need to change all the time.  This particular system was built by a team of duct tapers.  So our little struggle today is repeated over and over all day every day.  The net result is that it takes many times longer than it “should” to maintain and extend the system.  Indeed, some extenstions seem out of reach.  Conclusion: while duct tape systems may get to v1 faster, they can be very very expensive over the long term in terms of programming labor and worse yet in terms of  lost opportunity.

Blog at WordPress.com.