snappyco.de

rss

Shouldly

Shouldly is the "should" style test library you reach for when you've said "WTF just happened?!".

Pop quiz friend! Fix this error:

Expected 1337 but was 0

Ok, let me just set a breakpoint, fire up my debugger and...

Now stop right there! Put down that debugger and pick up Shouldly! It transforms your error into this:

contestant.Points should be 1337 but was 0

Ahhh! I get it, I need more points! But how do I write these magical tests? I LOVE MY NUNIT ASSERT.THAT!!

Really.

Yes

Really??

Yes!!

You like writing this?

Assert.That(contestant.Points, Is.EqualTo(1337));

YES!!

What if you could write your test like this!

contestant.Points.ShouldBe(1337);

ZOMG!1 Wow, what else can it do??

Well apart from having a whole host of "Shoulds":

ShouldBe
ShouldBeGreaterThan
ShouldBeLessThan
ShouldContain
ShouldNotContain
ShouldBeCloseTo

Wait, wait, shouldBeCloseTo?? Come on buddy, we're testing here, it's a precise activity, it's either equal or not, pass or fail, red or green capeche!?

Uh huh. Let's just say for interest, that you're testing XML in a string.

Ewwwwwww

It looks like this:

<enterprisey-configuration-block><enterprisey-logging>
    <loglevel alert="brown" />
  </enterprisey-logging>    </enterprisey-configuration-block>

Who formatted that so ugly!? Now we have to write an ugly string test to match it right? Wrong! I don't actually care if it doesn't match the whitespace properly:

xmlConfig.ShouldBeCloseTo(@"
<enterprisey-configuration-block>
  <enterprisey-logging>
    <loglevel alert='brown' />
  </enterprisey-logging>    
</enterprisey-configuration-block>");

Now we have a nice flexible test and our enterprise can sleep safe knowing it's precious xml is being cared for.

Notice the quotes around "brown"? Shouldly will do the compare, ignoring whitespace and not fussing over which quotes you used.

Ok Dave, this is cool and you're really awesome and stuff but what about when I get null refs in my mock tests or expectation violations?

Rhino.Mocks.Exceptions.ExpectationViolationException:
IContestant.PlayGame("Shouldly"); Expected #1, Actual #0

I still have to run up my debugger to figure out why my method didn't get called right??

You could do that.

Or, you could write your test like this:

contestant.ShouldHaveBeenCalled(c => c.PlayGame("Shouldly"));

and get this!

Expected:
  IContestant.PlayGame("Shouldly");
Recorded:
  IContestant.PlayGame("Debugging");
  IContestant.PlayGame("Logging");
  IContestant.PlayGame("Drinking coffee");
  IContestant.PlayGame("Commenting out test");

Now we see what's really happening here!

Wowee! How do I get started?

Just download or git clone http://github.com/snappycode/shouldly and either include it the source in your project or run msbuild and copy the dll into your repository.

Oh and feel free to fork and improve friends, let's all help each other out.

kick it on DotNetKicks.com

Fixing C# - Part II

This is part 2 of my series on making c# a nice language to work with. Previously I gave you flexible string quotation, today I present:

Regular Expressions as native types

Ever written code like this?

var money = Regex.Replace(@" $ 1,337", @"[\$\s\,]", "");

Regular expressions are so important to programming that they should be catered for in the language. At least Ruby and Javascript agree with me.

If c# understood regular expressions as a native type, we could have code like this:

var money = @" $ 1,337".Replace(/[\$\s\,]/, "")

You can instantly spot the regex, it doesn't have to be @ encoded into a string. We can also then have a replace method overload that takes a string or a regex type without any new Regex() bs.

Assert Awesomely

I've been working on nicer test code and error messages. Here's what I started with:

var steve = new Zombie();
Assert.That(steve.Mood, Is.EqualTo("I'm hungry for brains!"));

Which tells me

Expected string length 22 but was 27. Strings differ at index 1.
Expected: "I'm hungry for brains!"
But was:  "I want to shuffle aimlessly"
------------^

That's crap!

What I really wanted was a short behaviour style test and an error message that told me steve's mood was not what I expected it to be.

First the test syntax can be fixed with an extension method:

public static void ShouldBe<T>(this T actual, T expected)
{
    actual.AssertAwesomely(Is.EqualTo(expected), expected);
}

The test:

var steve = new Zombie();
steve.Mood.ShouldBe("I'm hungry for brains!");

Nice!

Now on to the error message. I did some experimenting with c#'s reflection and stack trace api and turned up the file and line number of the test that went kaboom! I then applied some loose morals and sweet regular expressions to turn the error into this:

steve.Mood 
    should be 
        "I'm hungry for brains!" 
    but was 
        "I want to shuffle aimlessly"

Not bad if I do say so myself.

And here's the code (Feel free to fork and improve). http://gist.github.com/252084

Fixing C#

For better or worse I spend a lot of time coding in c#. Bouncing back and forth between c#, ruby, javascript and objective-c I inevitably reflect a lot on the different language features and let me tell you that c# is my least favourite language to work in. But with a few improvements it could be made a passable programming language!

Of course I understand that c# is a static language and won't ever have all the awesomeness of a real dynamic type system, so I'm not advocating a full overhaul, just a few additions.

I'm going to start simple in this article and cover more in the future. So for today I present:

Flexible string quotation

Ever written code like this?

var message = "I heart \"unnecessary\" quotations";

All that messy quote escaping could be gone if we can quote strings with double or single quotes. We could rewrite that like this:

var message = 'I heart "unnecessary" quotations';

Much nicer!

My intro to Web Design

For such a snappy dresser I'm a horrible designer. I know what I like, I know what I don't like but given a blank canvas I stare at it for a while, give up, and watch the next episode of Lost. Luckily for me Andy Clark came to Sydney as part of the Web Directions Roadshow and taught me a few things. I think the biggest gain for me was discovering how much I don't know about design and the things I should focus on to improve. So here are a few great things I got out of the workshop.

Creativity, inspiration and getting ideas. Andy's inspirations come from a variety of sources such as print posters, newspapers and comic books. In fact, a big chunk of the day was spent on comic books alone! I've developed an appreciation for comics that I never had before.

One technique I really liked was to grab 100 images from flickr and create a 1 minute slideshow. This turned out to be very effective in conveying a mood or theme and a great way to inspire your designs.

He also spent a good section of time on typography and the idea that the content should drive the design. This is quite different to the common approach of designing the cms based site and then "pouring in the content". By the way if you're talking with typography peeps, leading is the size of the line or the vertical gap between lines, tracking is the horizontal space between letters and kerning is the space between two particular characters like V and A.

The last huge thing for me was discussing layout. It's all about the grid. Things that line up in a consistent way look better. A great layout should be essentially invisible because it will emphasize the content. Andy went through a bunch of ways that you can get a grid to base your layout on. From using photos of office buildings, to taking the images out of comic books, to using fibonacci or the golden ratio.

I'm planning on detailing my experiences with these techniques as I try things out, hopefully this post will serve as an introduction to what web designers think about. I will say though if you're interested in design and you get a chance to see Andy speak, I highly recommend going along.

Panels are teh suck

So I've been rocking SXSW for the last few days, having a blast. One thing not so fun is the panel format. Which basically means you get a few potentially interesting people together at a desk, get someone to ask them a few shallow questions and have them chat amongst themselves for an hour. Total suckage. I've yet to see it work, although Tim Lucas assures me that he did once actually witness this occurring.

Even though it may be possible to run an interesting panel, why!? Surely if we have smart people with smart things to say, they can prepare something, have an agenda, and present. Or if that's too difficult just get the audience to ask questions, you know those peeps who paid to hear people talk about stuff they found interesting.

Luckily there have been a few oasis's (wtf?) in the self-indulgent chat desert, a particular stand out for me was Lawrence Lessig's talk about how to restore faith in the American congress. It was well thought out, well spoken, well rehearsed and had a real point to be made. Walked out of the room totally charged, I almost wished I was american so could go and change congress.

Almost

I'm a sydney based software developer. I currently build stuff with ruby, c# and objective-c.

dave@snappyco.de

I'm on Twitter

I'm on Github