Sunday, February 22, 2009

Moq 3.0 released (With Full Silverlight Support)

Moq 3.0 has been officially released and it comes with full Silverlight Support. You can download them here http://moq.me/get

image

image image

Now that it is official and when I get some spare time I will try and place my UnityAutoMocker up in the moq-contrib project shortly.

Sunday, February 8, 2009

xUnit (Light) for Silverlight

If you've been doing any Silverlight development, I'm sure you're aware of the Microsoft Silverlight Unit Test Framework.

One extremely interesting aspect about this framework is how flexible it is for custom extension. If you didn't already know, Jeff Wilcox put together a quick port of NUnit and created a project that would interface the nunit.framework.dll he ported with the Microsoft Silverlight Unit Test Framework. (post here)

Below I'll explain a little about my port of the xUnit testing framework that is now hosted in the browser leveraging the Microsoft Silverlight Unit Test Framework.

As far as WHAT is implemented with the xUnit for Silverlight and what you may have to figure out on your own (as I'm not all that familiar with xUnit) if you use it for your own project...

  1. FactAttribute ( obviously )
  2. FactAttribute.Skip ( [Ignore] in most frameworks )
  3. FactAttribute.Name (is mapped to the "Description" in the ms test harness)

That's pretty much it... It doesn't do anything as far as test Setup/Teardown as Moq (the project I needed xUnit in Silverlight for) didn't need it, and because I'm not familiar enough with xUnit to really make this thing fully compatible.

So, here is XunitLight for Silverlight...

UPDATE: (2/9/2009) If you'd like to provide any updates to this project. You can get the source from below and I'm happy to take a look at patches...
http://svn.xp-dev.com/svn/staxmanade_projects/XunitLight.Silverlight/

Saturday, February 7, 2009

(-2) for [Fluent] Specification Extensions

If you read my previous posts about [Fluent] Specification Extensions then you know that I'm still in an experimental phase of this idea.

  1. Fluent Specification Extensions
  2. (+1) for [Fluent] Specification Extensions

There are two more things I've found that are going against the specification extensions idea. The first one below is related to all specification extensions, not just the fluent flavored specification extensions.

-1. If you have a test that for some reason has an assertion in the middle of some code.
[Fact]
public void MockAsExistingInterfaceAfterObjectSucceedsIfNotNew()
{
var mock = new Mock<IBag>();

mock.As<IFoo>().SetupGet(x => x.Value).Returns(25);

((IFoo)mock.Object).Value.ShouldEqual(25);

var fm = mock.As<IFoo>();

fm.Setup(f => f.Execute());
}

It's a little difficult to tell where the assertion is because you don't get the syntax highlighting help from the static class name "Assert".

Assert.Equal(25, (IFoo)mock.Object);

However I don't think the reason above is anything to stop using the pattern for a couple of the following:


  1. How often do you have assertions in the middle of your code?
  2. If you are doing your tests right, it doesn't take long to scan the above code for the ".Should..." extension method.
-1. Daniel from the Moq project tweeted Scott Bellware about his spec unit projects SpecificationExtensions.cs

@bellware shouldn't specunit ShouldNotEqual/etc. return the actual object rather than the expected? To chain other calls http://is.gd/iJuB

@bellware and ShouldBeNull/NotBeNull could also return the object: obj.ShouldNotBeNull().ShouldEqual(...), right?

with Scott's response being...

@kzu no because that would contribute to crowding many observations into a single method

To that I say, True, if you are doing pure Context/Specification based unit testing. However most of us aren't actually doing it (maybe we should?) so why not allow the test to say

someString
.ShouldNotBeNull
.ShouldEqual(...)?

So for now... I'm going to continue to go with the Fluent Specification Extensions.

Friday, February 6, 2009

(+1) for [Fluent] Specification Extensions

If you read my previous post about Fluent Specification Extensions then you know that I'm still in an experimental phase of this idea.

I'd like to share one more positive I found by using the specification extensions in my testing framework. This benefit is there weather you use standard specification extension methods or try the fluent specification extensions. The idea is very basic, but I didn't even realize it's benefit until I ran into it directly.

And the great benefit is... (drum roll...errr..actually it's not mind blowing). By using extensions methods to provide assertion extensions on the objects we're testing, we've abstracted the actual testing framework's assertion process. (told you it wasn't mind blowing, but read along and see an example of how this abstraction could be good)

Now I know most times you won't ever change testing frameworks, however I just ran into this when attempting to port the Castle.DynamicProxy2 (DP2) to Silverlight. Their test project leveraged the NUnit testing framework, which hasn't officially been ported. You can find a quick port by Jeff Wilcox that will run in the Microsoft Silverlight Unit Testing Framework. However when I was porting the DP2 that hadn't been done, and I didn't feel like porting NUnit at the time.

So, by providing this abstraction layer (through the extension methods). You could then go in and easily swap what testing framework your project is leveraging to do it's assertions.

NOTE: the port from NUnit to MSFT wouldn't have been that easy as the [TestMethod] in MSFT is sealed so I couldn't create a [Test] attribute that inherited from [TestMethod] to get the SL testing framework to run the tests w/out changing the DynamicProxy test code...aside from that issue...

Let's take a concrete example of this abstraction benefit.

Notice how the Assert.IsInstanceOfType() in both NUnit and Microsoft's testing framework have the parameters reversed.

NUnit:

image

Microsoft:

image

If you were trying to switch from NUnit to MSFT or visa versa, a simple search and replace on [Test] for [TestMethod] would suffice for the majority of the needed port. However the Assert.IsInstanceOfType() would fail at compile time because of the parameter order. (and who know what else exactly is different)

If you could provide that layer of abstraction for the assertions, then to switch between NUnit and MSFT or visa versa would remain very simple, as you would only have to provide the framework specific changes only once.

Wednesday, February 4, 2009

Fluent Specification Extensions

FYI: If you're familiar with extension methods, and how to use them in testing sceneries...the interesting part of this post is at the bottom starting at: "Ok, on to the point..."

The C# extension methods give some amazing power when it comes to extending functionality of objects (we don't own) and I've spotted a pattern on several blogs and example unit testing snippets, especially in the Context Specification style testing areas that I find interesting.

The concept is to basically use the C# extension methods within a unit testing environment to give the system under test (SUT) more readability/understandability within the test code itself.

Here's an example of how you might normally write a unit test given the following SUT.

public class SystemUnderTest
{
public SystemUnderTest() { PropertyUnderTest = "Hello World!"; }
public string SomeStringProperty { get; set; }
public bool SomeBoolProperty { get; set; }
}

You might write some unit tests that might look like...

var sut = new SystemUnderTest();

Assert.IsTrue(sut.SomeBoolProperty);
Assert.AreEqual(sut.SomeStringProperty, "Hello World!");

Now, the assertions above are small enough it's pretty easy to tell what's going on, however when you think about what your looking at, it actually present the best readability.

Let's take the string's AreEqual assertion for example...  You first read the "AreEqual", so now you have to allocate some (undefined as of yet) space in your head to store some data points that need to be evaluated all at once. (maybe I'm getting lazy as I get old, but the less I have to think when reading tests the more time I can spend understanding the domain being tested...)

Again, the example is over simplified, but I think you get the point.

What if you could make the test syntax read and flow in a very readable and understandable manner?

That's what the specification extensions give you. Given the two tests above and an a couple helper extension methods living in the testing library I could write something like.

var sut = new SystemUnderTest();
sut.SomeBoolProperty.ShouldBeTrue();
sut.SomeBoolProperty.ShouldEqual("Hello World!");

It may just be me, but that just feels better, is more understandable, and the great thing is I didn't have to impact my domain objects to support this style of test...

Another great benefit is you don't have to type "Assert.xxxx(YYzzz)" each time you want to create an assertion. You can just type sut.SomeThing.{this where you get help from intellasense} giving you some great context based assertion options.

I googled for a library that had a pre-built set of extension assertions and ended up finding the http://code.google.com/p/specunit-net/source/browse/ by Scott Bellware. If you dig into the source of the project you can find a helper class called SpecificationExtensions.cs which basically gives you all the "Should..{your assertion here}" extension methods.

Ok, on to the point real point (sorry it's taken so long).

After downloading and playing with the extension specifications from Spec Unit, I thought what if we made that more fluent?

So I gave it a quick spike and instead of writing some tests that look like...

sut.SomeStringProperty.ShouldNotBeNull();
sut.SomeStringProperty.ShouldBeOfType(typeof(string));
sut.SomeStringProperty.ShouldEqual("Hello World!");

You could have less wordy code and still retain all the meaning and readability with a set of fluent specification extensions.

sut.SomeStringProperty
.ShouldNotBeNull()
.ShouldBeOfType(typeof(string))
.ShouldEqual("Hello World!");

I haven't figured out what sorts of bad things this style of assertion could bring... but we'll experiment for a while...

Here's an example console app with the extensions included.

DISCLAIMER: I haven't tested all the extensions so if you notice any issues please feel free to let me know...

 

Copyright 2008 All Rights Reserved - Revolution Theme - by Brian Gardner. Converted into Blogger Template by Bloganol dot com