Wednesday, February 24, 2010

On the Utility of TestPropertyAttribute

On the project I’ve been working on lately, I’ve been using the unit test stuff that ships with Visual Studio/.NET, in the Microsoft.VisualStudio.TestTools.UnitTesting namespace. For my purposes, I’ve found it to be adequate, and it has the benefit that I don’t need to include any additional libraries.

I recently came across one use of it, however, that took me some time to figure out. Primarily because the documentation on this feature sucks pretty bad. It’s the TestPropertyAttribute, and it’s useful enough to be worth knowing about. So I thought I would share.

If you read the documentation for TestPropertyAttribute, your first reaction might well be the same as mine was: “Huh? That looks like it adds precisely no value over any other custom attribute I might write.” Because the docs show that to retrieve the value, you reflect against the test method it’s defined on, which is pretty silly. However, in experimenting, I found that there’s an equally poorly documented property on the TestContext class called Properties that you can use to get the value of this attribute.

Still, if you only need a value within the TestMethod itself, there’s not much value in it, as it’s no better than just hardcoding the value within the body of the test. Where TestProperty shines, though, is that the properties for the current test are also available during the TestInitialize method. That means you can bung a whole bunch of common setup code into your TestInitialize method, and parameterize its behavior based on properties defined on the tests themselves. A little code might help demonstrate what I mean:


1:
using System;


   2:  using System.IO; 


   3:  using Microsoft.VisualStudio.TestTools.UnitTesting;


   4:   


   5:  namespace Demo


   6:  {


   7:      [TestClass]


   8:      public class ThingTests


   9:      {


  10:          // Note that we have to have a TestContext, and it must


  11:          // be named TestContext


  12:          public TestContext TestContext { get; set; }


  13:   


  14:          // A simple field that we're going to initialize to 


  15:          // some value in the Initialize method.  


  16:          private string _thing; 


  17:          


  18:          [TestInitialize]


  19:          public void Initialize()


  20:          {


  21:              // Obviously we could do something much more complex here.


  22:              if (TestContext.Properties.Contains("thing"))


  23:              {


  24:                  _thing = TestContext.Properties["thing"] as string;


  25:              }


  26:              else


  27:              {


  28:                  _thing = "default"; 


  29:              }


  30:          }


  31:   


  32:          [TestMethod]


  33:          public void TestAgainstDefaultSetup()


  34:          {


  35:              Assert.AreEqual("default", _thing); 


  36:          }


  37:   


  38:          [TestMethod]


  39:          [TestProperty("thing", "non-default")]


  40:          public void TestAgainstCustomSetup()


  41:          {


  42:              Assert.AreEqual("non-default", _thing); 


  43:          }


  44:      }


  45:  }



Basically, we’ve got a field _thing that we usually want to leave at the default value of “default”, but in some tests we want to override to some other value. Moreover, we want to override it in the Initialize method, since that’s where we’re doing our setup that’s common across tests. – maybe we have fairly complicated setup that needs to differ only slightly in some tests. So we use the TestProperty attribute to set a property named “thing” to whatever we like. Then, in the Initialize method, we can use TestContext.Properties to check for the presence of that value and take appropriate action.

I’ve made the code intentionally trivial to more easily demonstrate the concept, but I’m sure you can visualize more realistic scenarios where this might come in handy. For example, I’ve used it to customize which directory my Initialize method operates on.

Tuesday, January 5, 2010

2009 – The Year in Review

With only six posts the entire year, 2009 was my lightest ever for blogging, although I continue to be active on Twitter (here). I don’t see that changing in 2010. Still, as is my custom, I post herewith a review of 2009, both personal and professional.

Looking back on my review of 2008, it seems that 2009 was a year of relative stability for me. I continued to work on pretty much the same stuff: primarily MSDN, but a few side projects whenever I could wedge in some free time. And outside of work, family consumes the bulk of my time, although I still manage to run and to occasionally do something else fun (like fly the Black Shark – ping me if you want to join us!).

The MSDN work has remained interesting, particularly in giving me the chance to work on Visual Studio 2010 itself. That’s right, I have code that will ship in the box! Specifically in the bit that supports offline help. It was quite an experience to work on so large a project, and I’m definitely looking forward to installing the final bits when they are released later this year.

A few random highlights from the year:

  • I bought an iPod Touch, which I totally love. I use it constantly, and if it ever broke I’d buy another on in a heartbeat.
  • Clojure remains the most interesting programming language I know. I donated twice in 2009, and would encourage you to do the same (donating just once would be fine). Even if you don’t care about Clojure - although any serious programmer owes it to themselves to check it out - I assure you that Rich is doing a lot to advance the state of the art in concurrent programming and is worthy of your support.
  • I read a graphic novel version of “The Hobbit” to my five-year-old…four times.
  • We made some progress on the basement, but am still (somewhat depressingly) not done.
  • I started using git seriously, and think it’s pretty cool.
  • I ran in a track meet for the first time since college. And didn’t suck…as much as I thought I would.
  • I started playing bass again. Badly, but I don’t care.
  • I saw four movies in an actual theater: Earth, Terminator, Harry Potter, Star Trek. That’s roughly four more than I usually see, at least since the kids were born.
  • We did lots and lots of travel: I was away from home for a cumulative total of over two months last year, including one trip to Asia. Alice and the girls were away for around three months if you add it up, including a second trip to Asia without me. Crazy.

As for what 2010 holds, I’m honestly not sure. On the personal front, it would be great to finish the basement. But bigger than that by far looms the shadow of Kindergarten, which our older daughter will enter in the fall. I’m sure it’ll be a big transition for everyone around here, particularly in the mornings, which tend to run on the late side most days. But we’ll handle it like we handle everything else. And I’m sure we’ll keep traveling, but hopefully not quite as much.

On the work front I really have no idea. I’m continuing to work with MSDN, and that will go on for at least a bit longer, but the life of an independent contractor is filled with uncertainty, and there’s the distinct possibility I’ll have to do a fairly serious (and possibly lengthy) search for work at some point. But as I’ve said before, it’s the rare challenge that doesn’t pose an opportunity.

Good luck to you in 2010!

Friday, October 30, 2009

Kim Wolk Gets a Blog

Excuse me while I blow the dust off the ol’ blog here.

So I see that Kim has a blog now. Finally. About time. See, Kim is one of the most effective people I’ve worked with in my career. And I’ve worked with her on many different projects for coming up on 15 years now. If she has something to do say, it’s worth listening to.

Subscribed!

Wednesday, August 5, 2009

MSDN Lightweight Mode

Long time, no blog. Mostly I update on Twitter now (http://twitter.com/craigandera) – it’s just easier to hurl a 140-character tidbit out than it is to write one of these posts. And I’m nothing if not lazy. But a reader posted a comment over here about MSDN Lightweight Mode. I checked it out, and it’s pretty cool, so I thought I would share it here on the blog, since I know not everyone watches my Twitter feed.

Anyway, have a look at http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates(lightweight).aspx (for example) and see what you think. I like it. I particularly like the fact that I can view just C# code (or just VB, or just whatever), as the noise generated by seeing all the languages is probably my only complaint with the loband view, which I still love and use as my primary interface to the MSDN website. 

I have no idea if this is an official thing, or an alpha that will disappear tomorrow, or what. Although I’m still doing work for MSDN, I only heard about this via the comment that Robert dropped on my blog. So hopefully I won’t get in trouble for sharing it, since I found out about it in public. :)

Check it out and see what you think.

Thursday, April 2, 2009

MSDN Loband Rocks

I mentioned MSDN Loband a few months ago. Well, they’ve updated it, and the update kicks some serious butt. Check it out here (the root of the MSDN library) or here (the docs for System.Xml.XmlReader, which show a more typical page). Note the navigation links on the left side, particularly the absence of the tree, and notice how much more streamlined – and therefore faster – the HTML is. I even had a friend tell me that it works pretty well on an iPhone over 3G…in New Zealand!

Now, once you’ve decided you like this version much better than the old one, click the “Persist low bandwidth view” link in the upper right corner and rejoice in the fact that you will always get this view.

I can pimp this one with a clear conscience because I had nothing to do with implementing it. Kudos to the team.

Wednesday, March 18, 2009

Using Extension Methods to Verify Assumptions

I was working on something with Tim yesterday, and between us we came up with what I think is a pretty cool trick. We were defining some extension methods on XElement and friends that make it easier to work work XHTML. Something like this:

doc.Html().Div(“foo”).Div(“bar”).Value

Which would pull out the text content of a div with a class of “bar” that was a descendant of a div with a class of “foo”. All well and good, but one of the problems we were trying to address is that we didn’t want to proceed if there was no div of class “foo”. A NullReferenceException would be thrown, but we wanted something more specific. So we came up with this:

public static T OrThrow<T>(this T obj, Exception e) {
    if (obj == null) {
        throw e; 
    } 
    return obj;
}

Which in turn allowed us to write this:

doc.Html().Div(“foo”).OrThrow(new MyException(“no foo”)).Div(“bar”).Value

The clever bit is that the OrThrow extension method is generic on the type it’s invoked on, and it returns that type, so you can insert it into a chained expression and you don’t lose any intellisense. And because of type inference, you don’t actually have to specify the type (you don’t have to type OrThrow<IEnumerable<XElement>>), which cleans up the expression a bit.

This approach is more general than just XHTML, of course. Really, it allows you to insert arbitrary assertions/checks into a series of chained calls using a fairly natural syntax (for some value of “natural”). Nothing you can’t do other ways, but we liked the way this came out enough to want to share it.

Friday, February 13, 2009

Hard Links in Windows Do Not Update Immediately

I was pretty excited when I saw mklink appear. Filesystem links can solve a lot of annoying problems, which is why you see them used all over the place in Unixy systems. Although, like salt, the key is to use them sparingly.

Which is why I’m so annoyed that the Windows version is pretty much completely useless. Soft links are only recognized in some contexts, but hard links are the real offender. Try this from an elevated command prompt:

> cd C:\temp
> echo foo > a.txt
> mklink /h C:\temp\hard-a.txt C:\temp\a.txt
> more hard-a.txt
foo

So far, so good. Now try this:

> echo more >> a.txt
> more hard-a.txt
foo
> more a.txt
foo
more
> more hard-a.txt
foo
more

WTF? My hard link doesn’t update immediately? That sucks!

From experimentation, it seems that it only updates after you’ve actually accessed the link once. Since one of the things I’d like to do is hardlink files into my Dropbox synchronization directory, this is pretty much a non-starter – they’ll never appear to be updated, and therefore will never sync. Unless I visit every file, which is pointless, because if I was going to do that, I could just copy them. Which is what I’m trying to avoid.

I’m more than willing to believe I’m missing something here, but if so I don’t know what it is. My best guess is that this is a bug in the filesystem caching code (I’m on Windows 2008).

Days like this make me want to switch full-time to my Ubuntu machine. Also not perfect, but at least the novelty makes me less sensitive to its shortcomings.