MbUnit... It's all green baby; it's all green!

Last night I started moving some of the PD logic out of the web project and into a Framework project so that it is more accessible to other components.  This resulted from some refactoring of the app. That I've been doing since implementing UrlRewriting and Trackbacks.  I created UrlManager, and UrlFormatter classes to handle some of the url matching logic and thought that I'd start building a library of Unit Tests against this new stuff. 

 

What I'm going to show you now is a bit of a code dump but, take a scan through it then we'll discuss what went on...

 

[TestFixture]
public class TestUrlManager {

  public TestUrlManager() {}

  [RowTest]
  [Row("http://www.projectdistributor.net", false)]
  [Row("http://projectdistributor.net", false)]
  [Row("http://www.projectdistributor.net/Foo", true)]
  [Row("http://www.projectdistributor.net/Projects/Project.aspx?foo=bar", false)]
  [Row("http://projectDistributor.net/", false)]
  [Row("http://projectDistributor.net/Foo/", true)]
  [Row("http://projectDistributor.net/Foo/default.aspx", true)]
  public void TestIsGroupInUrl(string url, bool isGroupUrl) {
    
    bool result = UrlManager.IsGroupNameUsed(url) ;
    Assert.AreEqual(isGroupUrl, result) ;

  }


  [RowTest]
  [Row("http://www.projectdistributor.net", "")]
  [Row("http://projectdistributor.net", "")]
  [Row("http://www.projectdistributor.net/Foo", "Foo")]
  [Row("http://www.projectdistributor.net/Projects/Project.aspx?foo=bar", "")]
  [Row("http://projectDistributor.net/", "")]
  [Row("http://projectDistributor.net/Foo/", "Foo")]
  [Row("http://projectDistributor.net/Foo/default.aspx", "Foo")]
  public void TestExtractName(string url, string groupName) {
    
    string result = UrlManager.ExtractGroupName( url ) ;
    Assert.AreEqual(groupName, result) ;

  }
}

 

...ok, as you can see, I'm testing the IsGroupNameUsed and the ExtractGroupName logic of the UrlManager class.  Notice how I can use attributes to drive test data into the test method by using the RowTestAttribute and the RowAttribute classes and attaching them to the methods that I want to run as unit tests.

 

The ease of TestDriven.NET

 

Because I'm using TestDriven.NET, I can now right click in the class, choose "Run Tests" and voila!  MbUnit presents me with a  web page representation of the red and green lights that you've seen via other unit testing frameworks such as Nunit.

 

Duplication kills

 

So that's pretty easy right?  Well, yes and no.  Look at that duplicated data there.  And what happens when I have 10 tests?  And what happens when I need to change the Row data?  That's right& all this duplication will end up working against me at some point.

 

Combinatorial Tests to the rescue

 

I knew that Peli would have the answer - after all, he did write it! - so, after a quick scan of his blog I discovered the combinatorial tests.

 

    http://blog.dotnetwiki.org/archive/2005/01/03/1403.aspx

 

Combinatorial tests allow me to create a factory which will produce my data and, for each enumerated item returned by the factory, a strongly typed data member can be returned to my unit test method.

 

Let's start& create a Data Class and a Factory

 

For my purposes a simple data class to encapsulate my test objects will suffice and then a simple factory method to create and return an array of that data:

 

// A simple data class to encapsulate the attributes of my driver data
public class UrlData {

  public UrlData( string url, string groupName ) {
    this.Url = url ;
    this.GroupName = groupName ;
  }

  public string Url;
  public bool IsGroup{ get{ return this.GroupName.Length > 0 } };
  public string GroupName;
}


[Factory]
public UrlData[] GetUrlData() {
  
  UrlData[] items = new UrlData[9] ;

  items[0] = new UrlData("http://www.projectdistributor.net", string.Empty) ;
  items[1] = new UrlData("http://projectdistributor.net", string.Empty) ;
  items[2] = new UrlData("http://www.projectdistributor.net/Foo", "Foo") ;
  items[3] = new UrlData("http://www.projectdistributor.net/Projects/Project.aspx?foo=bar", string.Empty) ;
  items[4] = new UrlData("http://projectDistributor.net/", string.Empty) ;
  items[5] = new UrlData("http://projectDistributor.net/Foo/", "Foo") ;
  items[6] = new UrlData("http://projectDistributor.net/Foo/default.aspx", "Foo") ;
  
  return items ;
}

 

Re-Wire and Re-run

 

Now, all that remains is to re-wire the test methods to use the factory and right click to re-run the tests again...

 

[CombinatorialTest]
public void TestIsGroupInUrl([UsingFactories("GetUrlData")] UrlData item) {
  
  bool result = UrlManager.IsGroupNameUsed( item.Url ) ;
  Assert.AreEqual(item.IsGroup, result) ;

}


[CombinatorialTest]
public void TestExtractName([UsingFactories("GetUrlData")] UrlData item) {
  
  string result = UrlManager.ExtractGroupName( item.Url ) ;
  Assert.AreEqual(item.GroupName, result) ;

}

 

It's all green baby; it's all green! :-)

 

1 Comment

Comments have been disabled for this content.