Friday, February 11, 2011

Announcing hspec

Announcing hspec - BDD for Haskell

I've long been interested in Behavior Driven Design and it's something that is strangely missing from the Haskell community. QuickCheck is an amazing tool that I use whenever I can, but BDD has it's uses too, even in Haskell.

hspec aims to be simple and there's only three functions that most people will need to use; describe, it, and hspec. Requirements are always about something and describe is how you say what they are about. describe takes the name of something and a list of requirements for it. The requirements themselves have a plain english description of desired behavior and some Haskell code that verifies the behavior is implemented correctly. The function it takes the english description and the verifying code. So describe and it are the two functions that package up something's requirements and verifiers into a list of Specs.


specs :: IO [Spec]
specs = describe "quantify" [
  it "makes single quantities singular"
    (quantify 1 "thing" == "1 thing"),

  it "makes larger quantities plural"
    (quantify 2 "thing" == "2 things"),

  it "makes zero quantities plural"
    (quantify 0 "thing" == "0 things"),

  it "treats negative quantities just like positive quantities"
    (quantify (-1) "thing" = "-1 thing"),

  it "handles words that end with an 'x' (eg box -> boxes)"
    (pending "no need for this yet")
  ]

hspec aims to be extendable so it is part of a type class, making it easy to add your own verifiers such as hUnit. The currently supported verifiers are an expression that reduces to a Bool, or you can use "pending", or you can use a QuickCheck property. The last requirement's verifier is "pending", representing the fact that this requirement isn't expected to be implemented yet so it doesn't have verifier code. That's all you need right there. Since the Specs are just a Haskell data structure you can evaluate them yourself to see what is successful and what is failing, no need for a test runner.

hspec aims to be useful and if you'd like an easy to read report then there's two extra functions pureHspec and hHspec. pureHspec takes a list of Specs and returns a nicely formatted list of strings documenting each spec and it's status. hHspec takes a handle and IO [Specs] and writes to the handle (usually stdout but it could be a file handle)


>> hHspec stdout specs

quantify
 - makes single quantities singular
 - makes larger quantities plural
 - makes zero quantities plural
 x treats negative quantities just like positive quantities
 - handles words that end with an 'x' (eg box -> boxes)
    # no need for this yet

Finished in 0.00021 seconds

5 examples, 1 failure

We see from the '-' that most requirements for quantify are met, the one with an 'x' is failing, and the one with a '#' and extra details is pending since there's no need for it yet. We also get a summary of how long it took and how many specs failed.

I've got some more ideas for it but I think it's simple enough, extendable enough, and useful enough to release to the Haskell community now.

hspec can be found on github at https://github.com/trystan/hspec

Wednesday, February 9, 2011

Understanding vs NUnit

Can you tell what MysteriousMethod does from looking at these C# unit tests?
  [Test]
  public void Test1()
  {
    var obj = new MysteriousObject();
    Assert.IsTrue(obj.MysteriousMethod(8));
  }

  [Test]
  public void Test2()
  {
    var obj = new MysteriousObject();
    Assert.IsFalse(obj.MysteriousMethod(11));
  }

Maybe it returns true if the input is even, or a single digit, or if it's not prime, or if it's divisible by 4 or 8, or maybe it only returns true for the number 8, I don't know. All I do know is that it returns true for 8 and false for 11.

Can you tell what mysteriousFunction does from looking at these Haskell QuickCheck properties?

  prop_test1 :: Int -> Bool
  prop_test1 x = x `mod` 4 == 0 ==> mysteriousFunction x

  prop_test2 :: Int -> Bool
  prop_test2 x = x `mod` 4 /= 0 ==> not $ mysteriousFunction x

It looks like it returns true if the input is divisible by four and false if it isn't. Pretty clear to me.



I'm working on a Haskell project and it's reminding me why I like QuickCheck so much. Not only does it do a much better job at catching unexpected cases but the meaning and intention of each function is so clear, much clearer than when using xUnit style testing. Going back to C# and NUnit feels weird; you're basically just comparing hard coded values. I find it hard to tell why one value is used instead of something else, i.e. what's essential and what's accidental, especially when the method being tested has several inputs or other variables it relies on. This can lead to bad assumptions and misunderstanding what something actually does. With QuickCheck there's less room for such confusion because the focus is on properties of the values and not the specific values themselves. The clarity of BDD tools (rspec, etc) seems to help, but I wonder what more can be done.

Wednesday, February 2, 2011

Interfaces as object contexts

Here's a possibly useful idea I came up with a few weeks ago. I've come across situations where an object needs different behavior depending on the context or how it's used. Usually the state or strategy design pattern (or a mess of if statements) can handle this, but so can explicit interfaces in C#.

First make an interface for each set of behavior you want.

interface IContextA
{
  string Property { get; }
  int Method(int data);
}

interface IContextB
{
  string Property { get; }
  int Method(int data);
}

Then create the different contexts or scenarios using the interface with the behavior you want.

static void DoStuffInContextA(IContextA example)
{
  Console.WriteLine(example.Property);
  Console.WriteLine(example.Method(8));
}

static void DoStuffInContextB(IContextB example)
{
  Console.WriteLine(example.Property);
  Console.WriteLine(example.Method(8));
}

Then create a class that implements the different behavior.

class MultiContextObject : IContextA, IContextB
{
  string IContextA.Property
  {
    get { return "called in context a"; }
  }

  int IContextA.Method(int data)
  {
    return data + 1;
  }

  string IContextB.Property
  {
    get { return "called in context b"; }
  }

  int IContextB.Method(int data)
  {
    return data - 1;
  }
}

And now you can use interfaces to select which set of behavior you want your object to use.

static void ExplicitInterfaceAsContextTest()
{
  MultiContextObject example = new MultiContextObject();
  DoStuffInContextA(example);
  DoStuffInContextB(example);
}

I think this is neat. It won't replace state and strategy patterns, but there's probably cases where those aren't possible or where this would work better.

Friday, January 14, 2011

Enum subsets in C#

After a few years of working with Haskell I've become nearly obsessed with expressing constraints in the type system. Although the C# type system isn't as expressive as Haskell's, preconditions, postconditions, ranges, complexity, and other things can be expressed. If the type is expressive enough then you don't even have to do any validation or checking when working with it because the compiler already guaranteed that the data is valid. One of the problems with C# enums is that they aren't real objects so they can't subclass; they're just pretty wrappers around primitives like ints or bytes. This means that if you only allow certain values of an enum then you have to manually check at runtime:

public void DeclareDayIsSpecial(DayOfWeek day)
{
  if (day == DayOfWeek.Sunday || day == DayOfWeek.Saturday)
    throw new ArgumentException("When declaring that a day is special, the day must be a weekday.", "day");
 
  Console.WriteLine("{0} is special.", day);
}

Even though you can't define an enum as a subclass of another and allow only that subclass, you can define an enum as subset of another.

public enum Weekday
{
   Monday = DayOfWeek.Monday,
   Tuesday = DayOfWeek.Tuesday,
   Wednesday = DayOfWeek.Wednesday,
   Thursday = DayOfWeek.Thursday,
   Friday = DayOfWeek.Friday,
}

Once you have this you can constrain your methods to just the valid subset of values.

public void DeclareDayIsSpecial(Weekday weekday)
{
  Console.WriteLine("{0} is special.", weekday);
}

The compiler won't allow you to use an invalid value so you have compile time documentation and feedback and can remove the runtime checks. This can be useful if you use enums in a scenario where only some values are valid. And since enums are wrappers around primitive types, you can safely cast from the subset (Weekday) to the superset (DayOfWeek).

Thursday, January 6, 2011

Programming and a theory of mind

A couple days ago I realized that programming is by far the most social thing I do. Sure, I discuss things with other developers, QA, and business analysts, but that's a small part of my time. The vast majority of my time is spent looking at what is already there and trying to understand it. Not just what it does or how it does it, but why. And this requires a Theory Of Mind.

A theory of mind is when you realize that other people have their own mind and their own ideas that are separate and different from yours. Everything I see at work isn't some naturally occurring thing - it was created by someone, it has an intended purpose, a reason for being, some business or technical need that it meets. Much of my time is spent interacting with others but only when programming do I need to look into so many other minds at the same time, to find and understand the intent of the original developer, the business scenario being addressed, the reasons why it was done this way and not that way, and why it's still being done this way. Writing code generally isn't difficult, especially business apps, it's understanding the intent and reasons for the code that's tough. Like it says in Structure and Interpretation of Computer Programs, "Programs should be written for people to read, and only incidentally for machines to execute."

Wednesday, December 29, 2010

An algorithm to find floating holidays

I've always liked dealing with code that works with dates and times. You learn a lot about our calendars and all the hacks to make up for our inaccurate decisions hundreds of years ago and for the earth's wobbles and year-to-year inconsistencies.

One task that's come up again and again is determining floating holidays. Here's a very quick and easy way I discovered to determine floating days (every 4th thursday etc) and fixed days that are observed on friday or monday when the day is a holiday.

All you need is a list or array of the 7 days of the month it falls on. The first element is the day of the month the holiday is on when the month begins on a Sunday, the second element is the day of the month the holiday is on when the month begins on a Monday, and so on. Once you find what day of the week the month starts on, you can just lookup the day you're looking for. So you know the year, the month, and the day the holiday falls on for any year of that calendar.

For example, American Independence day is celebrated on the 4th of July or the closest weekday when it falls on a weekend. Using a calendar we can see that the days of the month are [4,4,4,3,5,4,4], i.e. when July starts on a Wednesday (4th element in the list) the holiday is celebrated on the 3rd, when it starts on a Thursday (5th element in the list) the holiday is celebrated on the 5th, otherwise it's celebrated on the 4th. American Thanksgiving day is celebrated on the 4th Thursday of November so the days of the month are [26,25,24,23,22,21,27], i.e. when November starts on a Sunday the holiday is celebrated on the 26th, when November starts on a Monday the holiday is celebrated on the 25th, etc.

The java is much less verbose than the english description:


public Calendar getAmericanIndependanceDay(int year){
        return getFloatingDay(year, 6, new int[]{4,4,4,3,5,4,4});
    }

    public Calendar getAmericanThanksgivingDay(int year){
        return getFloatingDay(year, 10, new int[]{26,25,24,23,22,21,27});
    }

    private Calendar getFloatingDay(int year, int month, int[] days){
        Calendar firstDayOfTheMonth = new GregorianCalendar(year, month, 1);
        int firstDayOfTheWeek = firstDayOfTheMonth.get(Calendar.DAY_OF_WEEK) - 1;
        return new GregorianCalendar(year, month, days[firstDayOfTheWeek]);
    }

Thursday, December 23, 2010

Unit tests are not inherently good

Unit tests cause pain. Unit tests, by themselves, do not solve problems, do not make users happy, do not make maintainers happy, do not make a better product, and do not improve design. Unit tests make certain things hurt; nothing more and nothing less. But pain can indicate something is wrong and can lead you to do something else.

The first assumption behind unit tests (and bodily pain) is that if something hurts we'll pay attention and do something else instead. The second assumption is that what we do as an alternative will not only hurt less but make things better. For example, since unit tests make singletons and hard coded dependancies so painful, we can rely on dependency injection techniques and the single responsibility principal. This should cause code that is easier to test and understand and that responds to rapidly changing requirements.

So unit tests are one way to show what hurts and needs attention and avoid blundering into bad and potentially project-killing designs. The problem is when we can't or don't change how things are done. If we must rely on singletons, the filesystem, database, complex api calls, undefined behavior, or slow techniques then writing and running the unit tests will hurt. In these cases the costs of writing and maintaing unit tests can outweigh the benefits of running those tests.