C# Anonymous Delegates, MVP, and testing with NUnitForms

Posted by Paul Ingles
Monday, July 16, 2007 20:01:00 GMT

I’m not sure why, but I get the feeling that anonymous delegates in C# 2.0 haven’t really had much of a press and people aren’t really that aware of them.

Essentially, it lets you declare the delegate inline a la:

public delegate void MyDelegate();
  ...
  private void DoIt(MyDelegate codeBlock)
  {
    codeBlock();
  }
  public void AddInstrumentToPrice(string message)
  {
    DoIt(delegate { Console.WriteLine(message); });
  }

Closures!

On my current project we’ve found some great use for them, in particular, once we’d started refactoring some GUI code into the Model-View-Presenter pattern as described in Michael Feathers’ Humble Dialog paper (pdf). This tidied a lot of the code up nicely, keeping the GUI code focused, allowing us to then focus a little more on improving the behaviour of the UI.

The Windows Forms UI needed to show a progress bar indicating how far it was through pricing all of the selected trades. But, with our pricing occurring within the same thread our UI was locking. So, you push the processing out into a worker thread and then you can update both, right? Wrong, because .NET will throw an exception should you attempt do this - because Windows itself doesn’t like it when you do.

The Control class includes an Invoke method that executes a Delegate on the UI thread. So, to ensure our UI updates execute on the UI thread we can write the following

public void calculateButton_click (object m, mouseeventargs e) {
  this.Invoke(delegate { resultsList.Items.Add("a result!") });
}

Testing With NUnitForms

Once we had that written, we had an additional problem - we now had code executing on different threads making it difficult to test through the GUI. Sure, we had a lot of tests that drove out the implementation of the Presenter, but, it’s always nice to know that the GUI is behaving, and you’re driving something end to end.

Our solution — use the Strategy pattern to extract out the behaviour around how code is executed in the GUI, we use an anonymous method/delegate to pass a code block to a class that either executes it on the same thread (for our tests), or, uses ThreadPool.QueueUserWorkItem.

So our end-to-end NUnitForms test might look something like

[SetUp]
public void Initialisation() {
  form = new SampleForm(new SameThreadWorker());
}

class SameThreadWorker : IWorker {
  public void Do(WaitCallback block) {
    block(null);
  }
}

[Test]
public void ShouldShowResultInListAfterCalculating() {
  ClickButton("calculateResults");
  Assert.IsTrue(ListContains("resultsList", "My Result"))
}

Which is handled inside the form by

public void calculateButton_click (object m, mouseeventargs e) {
  worker.Do(delegate { resultsList.Items.Add("a result!") });
}

And our default worker for the GUI? Something a little like

class UserWorkItemWorker : IWorker {
  public void Do(WaitCallback block) {
    ThreadPool.QueueUserWorkItem(block);
  }
}

Probably not the best way of doing it, but certainly better than most I could think of, and all thanks to anonymous delegates.

ReSharper 2 is shaping up!

Posted by paul
Wednesday, March 22, 2006 10:11:00 GMT

I’ve been so busy with Rails of late, as well as working on .NET 1.1 code that I’ve not really had the opportunity to dive into using Visual Studio 2005.

Over the last 2 days I’ve been using it almost exclusively (the rails work is a lower priority right now). Most of it I’d say is a big improvement, at least in terms of it not hanging (which 2003 used to do almost hourly for me).

However, the thing I’m really hankering after is the solid release of ReSharper from the brilliant guys at JetBrains. And here’s why …

Visual Studio the first to offer integrated Unit Testing

Posted by paul
Tuesday, March 14, 2006 18:31:00 GMT

You read it here first (well, you didn’t really—it’s Visual Studio Magazine that’s making the rather grandiose assertion in this article).

A message was posted to the XP mailing list earlier today that thanked the article for not calling it Test-Driven Development (due to the last fiasco where Microsoft seemed to have bungled their intepretation of test driven development with regard to their integrated testing tools).

However, in the first paragraph of the article is the following nugget:

“To be fair, it isn’t just the Visual Studio IDE that lacked integrated unit testing. None of the major development environments—and this includes Java IDEs—have integrated unit testing directly into the development IDEs. The Visual Studio Team System (VSTS) edition of Visual Studio 2005 corrects this …”

Now, admittedly my exposure to other IDEs is pretty limited (I’m primarily a .NET developer) but both Eclipse and IDEA when I used them had JUnit integrated nicely. Victor Goldberg followed up later mentioning a Smalltalk IDE that had a TDD framework built-in. So there are definitely other IDEs that have unit testing integrated.

Now, it’s true that this is the first time unit testing has been directly integrated into Visual Studio by Microsoft, but there have been add-ins for doing the same thing for some time (TestDriven.NET is the shining example). So part of the assertion is true. But, it’s just plain wrong to state that “[none] of the major development environments—and this includes Java IDEs—have integrated unit testing”.

Of course it’s possible my interpretation is a little different to what was intended, but I’m not sure it is. A more realistic explanation is that the language is a little looser than it should be and that Visual Studio is the first to provide an integrated, out of the box unit testing framework, which, is still something I’m a little unsure is true—my recollection is both IDEA and Eclipse had it out of the box, but maybe that’s just my memory?

Either way, it’s this definition of integration that bothers me. Why is it so much better that it’s provided by Microsoft straight away? It doesn’t take much to install the add-ins for the various IDEs, and more importantly, they appear to be far better (at least in Visual Studio’s case anyway). Visual Studio’s integrated unit testing appears to be entirely inadequate for those wanting to work test first with Test Driven Development, so I think I’ll stick with the free tools that work better thanks!

ASP.NET Developers, how important is Control testability to you?

Posted by Paul Ingles
Monday, January 23, 2006 14:09:00 GMT

A while ago, Avi posted a message to the Test Driven Development Yahoo! groups list entitled “Testing form validation in ASP.NET”.

He was working around the Model/View/Presenter pattern, and was trying to discover a way to test form validation on the client-side. Although one could implement validation within the presenter itself, he was worried validation would be repeated in multiple locations—on the client-side, within the presenter, and finally the ASP.NET validation server controls themselves.

Rightly, he chose to ignore my advice—I tend to have a way of suggesting rather grandiose solutions to problems :), but the thought has stuck with me. ASP.NET doesn’t make testing easy, and validation is (but) one aspect that it would be useful to exercise independently of the GUI.

In my experience, I’ve not found a good way to test ASP.NET controls without needing to run some kind of through-the-GUI test, and by that I mean testing by exercising the web application the controls sit in.

Although this is useful for integration testing, when starting out it’s a little heavy-weight and requires me to move in larger-than-baby-steps, and often with bad consequence.

So I’m wondering how important testability of controls (and validation in particular) is to other ASP.NET developers?

I’ve written a few validators in the past, and I very am interested to improve the quality of the code now that I’m a little older and (hopefully) wiser. Since Avi’s post surfaced (and I thought about what I’d like to do if it were me), I’m considering widening the scope of my current validation control re-writes—to include a more generic validation framework that is simpler to plug into ASP.NET, reduces the coupling, and more importantly, increases testability outside of the GUI.

Anyway, just wondering whether any other ASP.NET developers have had any validation testing nightmares? Is it enough of a headache to move to a different set of validator controls?

ASP.NET Developers, how important is Control testability to you?

Posted by paul
Monday, January 23, 2006 14:09:00 GMT

A while ago, Avi posted a message to the Test Driven Development Yahoo! groups list entitled “Testing form validation in ASP.NET”.

He was working around the Model/View/Presenter pattern, and was trying to discover a way to test form validation on the client-side. Although one could implement validation within the presenter itself, he was worried validation would be repeated in multiple locations—on the client-side, within the presenter, and finally the ASP.NET validation server controls themselves.

Rightly, he chose to ignore my advice—I tend to have a way of suggesting rather grandiose solutions to problems :), but the thought has stuck with me. ASP.NET doesn’t make testing easy, and validation is (but) one aspect that it would be useful to exercise independently of the GUI.

In my experience, I’ve not found a good way to test ASP.NET controls without needing to run some kind of through-the-GUI test, and by that I mean testing by exercising the web application the controls sit in.

Although this is useful for integration testing, when starting out it’s a little heavy-weight and requires me to move in larger-than-baby-steps, and often with bad consequence.

So I’m wondering how important testability of controls (and validation in particular) is to other ASP.NET developers?

I’ve written a few validators in the past, and I very am interested to improve the quality of the code now that I’m a little older and (hopefully) wiser. Since Avi’s post surfaced (and I thought about what I’d like to do if it were me), I’m considering widening the scope of my current validation control re-writes—to include a more generic validation framework that is simpler to plug into ASP.NET, reduces the coupling, and more importantly, increases testability outside of the GUI.

Anyway, just wondering whether any other ASP.NET developers have had any validation testing nightmares? Is it enough of a headache to move to a different set of validator controls?

Of Is and As (Operators in C#)

Posted by Paul Ingles
Wednesday, January 11, 2006 20:01:00 GMT

It’s been a while since I made any .NET posts, but here’s one that’s been bubbling up for too long!

I have to confess to being a little bit ‘militant’ to certain things I see in code. Blindly catching `Exception` is one thing that gives me shivers, using the `as` operator everywhere is another.

The issue I take is one of code semantics and intent, and consequently readability. For example, take the following piece of C# code:

Person personPaul = ...;
Man paul = (Man)personPaul;

When I read the above, I take it to read that I fully expect to be able to treat `personPaul` as a `Man`, that `personPaul` categorically can be cast successfully.

However, the following is subtly different:

Man paul = personPaul as Man;

This statement uses the `as` operator which attempts to perform the specified cast, but, if it fails instead of throwing an `InvalidCastException`, it will return `null`. In the example above, the use of `as` implies a statement along the lines of “I’d like to treat `personPaul` as a man, but if I can’t, I’m not too worried”. If we know that an object is of type `T`, I don’t see the need to use a cast that handles a situation when it isn’t.

Where the `as` operator is intended for use is in situations to avoid the expensive CLR checks associated with casting in a code pattern such as this:

if (personPaul is Man) {
    Man paul = (Man)personPaul;
}

In this situation we’re actually performing two casting operations:

L_0000: ldarg.0 
L_0001: isinst Man
L_0006: brfalse.s L_002f
L_0008: ldarg.0 
L_0009: castclass Man

Notice the calls to `isinst` and `castclass`—in both cases the CLR will perform a check to determine whether the object in question is cast-able. Since we definitely know by line `L_0009` we’re looking at a `Man` (since we’ve already performed one cast operation on `IL_0001` that returns us from the routine if it fails), there’s no need for the CLR to perform an additional check.

In these situations, it’s much better to use the `as` operator as mentioned earlier, which ultimately results in something similar to:

L_0000: ldarg.0 
L_0001: isinst Man
L_0006: stloc.0 
L_0007: ldloc.0 
L_0008: brfalse.s L_002c
L_000a: ldloc.0 
L_000b: call void Test::DoSomething(man)

In this case we’re only doing the cast once, reducing the number of expensive CLR type safety checks. Admittedly, there are far more things that could cause your code to slow down but the key benefit for me is that it makes the code easier to read and any invalid operations will result in a far more meaningful `InvalidCastException`, rather than a `NullReferenceException`.

Incidentally, one other important note that I stumbled across is that casting using the `as` operator will not use any conversions that you specify, that would normally be performed when using casting syntax.

Of Is and As (Operators in C#)

Posted by paul
Wednesday, January 11, 2006 20:01:00 GMT

It’s been a while since I made any .NET posts, but here’s one that’s been bubbling up for too long!

I have to confess to being a little bit ‘militant’ to certain things I see in code. Blindly catching `Exception` is one thing that gives me shivers, using the `as` operator everywhere is another.

The issue I take is one of code semantics and intent, and consequently readability. For example, take the following piece of C# code:

Person personPaul = ...;
Man paul = (Man)personPaul;

When I read the above, I take it to read that I fully expect to be able to treat `personPaul` as a `Man`, that `personPaul` categorically can be cast successfully.

However, the following is subtly different:

Man paul = personPaul as Man;

This statement uses the `as` operator which attempts to perform the specified cast, but, if it fails instead of throwing an `InvalidCastException`, it will return `null`. In the example above, the use of `as` implies a statement along the lines of “I’d like to treat `personPaul` as a man, but if I can’t, I’m not too worried”. If we know that an object is of type `T`, I don’t see the need to use a cast that handles a situation when it isn’t.

Where the `as` operator is intended for use is in situations to avoid the expensive CLR checks associated with casting in a code pattern such as this:

if (personPaul is Man) {
    Man paul = (Man)personPaul;
}

In this situation we’re actually performing two casting operations:

L_0000: ldarg.0 
L_0001: isinst Man
L_0006: brfalse.s L_002f
L_0008: ldarg.0 
L_0009: castclass Man

Notice the calls to `isinst` and `castclass`—in both cases the CLR will perform a check to determine whether the object in question is cast-able. Since we definitely know by line `L_0009` we’re looking at a `Man` (since we’ve already performed one cast operation on `IL_0001` that returns us from the routine if it fails), there’s no need for the CLR to perform an additional check.

In these situations, it’s much better to use the `as` operator as mentioned earlier, which ultimately results in something similar to:

L_0000: ldarg.0 
L_0001: isinst Man
L_0006: stloc.0 
L_0007: ldloc.0 
L_0008: brfalse.s L_002c
L_000a: ldloc.0 
L_000b: call void Test::DoSomething(man)

In this case we’re only doing the cast once, reducing the number of expensive CLR type safety checks. Admittedly, there are far more things that could cause your code to slow down but the key benefit for me is that it makes the code easier to read and any invalid operations will result in a far more meaningful `InvalidCastException`, rather than a `NullReferenceException`.

Incidentally, one other important note that I stumbled across is that casting using the `as` operator will not use any conversions that you specify, that would normally be performed when using casting syntax.

Access to my CodeProject code in Subversion

Posted by Paul Ingles
Wednesday, January 11, 2006 15:37:00 GMT

It’s been a while since I last posted, and it’s been even longer since I posted about anything .NET-related—I’ve been knee deep in freelancing work playing with Ruby on Rails. But, after an email from someone using some of my old CodeProject code I figured it was time to get my stuff in order!

A while ago I posted that I was in the process of moving some projects of mine into open source, and away from their current home on CodeProject.

I suppose it’s not really a move into open source as such, but a move into an environment that makes maintenance/updates to the code as easy as possible.

At present, all articles require me to submit both HTML and code updates to editors, upon which changes are updated and new zip archives made available. This is a relatively longwinded process and makes quick changes rather painful.

So instead, all code will be hosted in a brand new Subversion repository I will host. Instead of releasing zip files, all users can grab the latest source by checking out from the repository.

All repositories follow the standard trunk/branches layout. For users that aren’t familiar, the trunk contains the development mainline—that is the stable code that you should be using. Branches will be used sparingly for larger breaking changes, until they are in a state to be merged. There’s no reason you can’t use the code from one of these too, but bear in mind it’s probably a little more rough and ready.

So, for those that aren’t familiar with using Subversion, here’s how you go about using it.

1. Download a client 2. Checkout the mainline branch for your projects, using the following:

svn checkout http://url/project/trunk project

That’ll put a copy of the trunk into the project directory (the last parameter). That ought to be all you need to do. However, if you find you make improvements/fixes it’d be nice if you contributed those.

To do so, you’ll need to run

svn diff > my_changes_patch.txt

That’ll generate a file containing enough information for another user to apply the changes outside of the usual repository. This is to ensure that the repository isn’t open to abuse from all, all changes should instead be emailed to me (please note you’ll need to update my email address there). Provided they look ok I’ll stick them into the trunk for everyone else to then update via running

svn update

So far I’ve added the following projects:

I will consider adding automated binary builds for the stable releases, but this isn’t a priority at the moment so I’m afraid it’s just the repositories.

Note: It’s taken me a little longer than expected to get things going, so I’ll be adding the remaining projects as soon as I can, until then, feel free to grab away! One of the things I’d like to add is some kind of unit and functional testing, the gauntlet has been set!

Access to my CodeProject code in Subversion

Posted by paul
Wednesday, January 11, 2006 15:37:00 GMT

It’s been a while since I last posted, and it’s been even longer since I posted about anything .NET-related—I’ve been knee deep in freelancing work playing with Ruby on Rails. But, after an email from someone using some of my old CodeProject code I figured it was time to get my stuff in order!

A while ago I posted that I was in the process of moving some projects of mine into open source, and away from their current home on CodeProject.

I suppose it’s not really a move into open source as such, but a move into an environment that makes maintenance/updates to the code as easy as possible.

At present, all articles require me to submit both HTML and code updates to editors, upon which changes are updated and new zip archives made available. This is a relatively longwinded process and makes quick changes rather painful.

So instead, all code will be hosted in a brand new Subversion repository I will host. Instead of releasing zip files, all users can grab the latest source by checking out from the repository.

All repositories follow the standard trunk/branches layout. For users that aren’t familiar, the trunk contains the development mainline—that is the stable code that you should be using. Branches will be used sparingly for larger breaking changes, until they are in a state to be merged. There’s no reason you can’t use the code from one of these too, but bear in mind it’s probably a little more rough and ready.

So, for those that aren’t familiar with using Subversion, here’s how you go about using it.

1. Download a client 2. Checkout the mainline branch for your projects, using the following:

svn checkout http://url/project/trunk project

That’ll put a copy of the trunk into the project directory (the last parameter). That ought to be all you need to do. However, if you find you make improvements/fixes it’d be nice if you contributed those.

To do so, you’ll need to run

svn diff > my_changes_patch.txt

That’ll generate a file containing enough information for another user to apply the changes outside of the usual repository. This is to ensure that the repository isn’t open to abuse from all, all changes should instead be emailed to me (please note you’ll need to update my email address there). Provided they look ok I’ll stick them into the trunk for everyone else to then update via running

svn update

So far I’ve added the following projects:

I will consider adding automated binary builds for the stable releases, but this isn’t a priority at the moment so I’m afraid it’s just the repositories.

Note: It’s taken me a little longer than expected to get things going, so I’ll be adding the remaining projects as soon as I can, until then, feel free to grab away! One of the things I’d like to add is some kind of unit and functional testing, the gauntlet has been set!

Building the Build

Posted by Paul Ingles
Friday, December 02, 2005 09:54:00 GMT

Despite having already used many of the tools I’m using to provide the build environment for EmailValidator, it still took longer than expected, so here’s the highlights of the current structure which will no doubt change as the project evolves.

The aim of the build is to provide both a) an easy way for end-users and project developers to build project consistently, and b) provide a means for a continuous integration server to regularly build the project. The continous integration server is key to ensure that when other code is contibuted, it is built and tested and that any failure is fixed as quickly as possible. The aim is to also automate the publishing of builds and testing results to this website.

Continuous integration isn’t a particularly new term, it’s origins area in the daily ‘build and smoke’ test, but is one of the key tenets of eXtreme Programming. The idea of automated tests that fully exercise the codebase is key to the overall vision of a high quality product.

The build process:

1. Clean any previous build’s output 2. Build the project 3. Run automated tests 4. Produce code-coverage reports

For this project, I’m using NAnt 0.85rc3 (built 16/04/2005) to actually perform the build – taking the source code, compiling it, running tests etc. Once the project has been built it’s then time to run the tests, these are done using NAnt’s built-in NUnit task. Finally, code-coverage is provided by Clover.NET.The continuous integration server I’m using is CruiseControl.NET which will currently be running in the background as a service on my development machine.

Clover.NET proved to be the most difficult to wire-in, but this was down to it not being entirely clear which build of CloverNAnt to use, as it happens, it was 0.85.2053. A more recent build (2100) I believe is to fix breaking changes in 0.85rc3+ builds.

Firstly, we load information from CloverNAnt’s assemblies:

This ensures we don’t need to copy the assembly over to NAnt’s directory. The current Subversion repository for the project has both NAnt and NAntContrib under source control – a practice I’ve seen recommended in a few places, including John Robbins’ excellent so this keeps everything nice and clean and tidy.

Clover.NET works by instrumenting the code before compilation, writing in additional instructions to generate a database of results during execution. So, before compilation, we use the following tasks:

/tests//”/> <mkdir dir=”${tests.dir}” unless=”${directory::exists(tests.dir)}” />

Since the clover-setup task **doesn’t automatically create the CloverBuild folder (where it temporarily writes instrumented code to) it’s necessary to create the directory first. The exclusion mask ensures that we don’t instrument (and thefore check coverage) of the test fixtures themselves – just the classes under test. The other thing of note is the final line – CloverNAnt relies on the CloverRuntime assembly to work, and for our tests to run, we’ll need to have the CloverRuntime assembly in the same path. Since all test assemblies are written to the same folder, we just need the one location. Once that’s been done it’s time to execute the tests as normal, and produce the coverage report.

Since this is already long enough (and has taken longer than expected to write) I’ll save the Continuous Integration aspect of the build system for the next post!

Building the Build

Posted by paul
Friday, December 02, 2005 09:54:00 GMT

Despite having already used many of the tools I’m using to provide the build environment for EmailValidator, it still took longer than expected, so here’s the highlights of the current structure which will no doubt change as the project evolves.

The aim of the build is to provide both a) an easy way for end-users and project developers to build project consistently, and b) provide a means for a continuous integration server to regularly build the project. The continous integration server is key to ensure that when other code is contibuted, it is built and tested and that any failure is fixed as quickly as possible. The aim is to also automate the publishing of builds and testing results to this website.

Continuous integration isn’t a particularly new term, it’s origins area in the daily ‘build and smoke’ test, but is one of the key tenets of eXtreme Programming. The idea of automated tests that fully exercise the codebase is key to the overall vision of a high quality product.

The build process:

1. Clean any previous build’s output 2. Build the project 3. Run automated tests 4. Produce code-coverage reports

For this project, I’m using NAnt 0.85rc3 (built 16/04/2005) to actually perform the build – taking the source code, compiling it, running tests etc. Once the project has been built it’s then time to run the tests, these are done using NAnt’s built-in NUnit task. Finally, code-coverage is provided by Clover.NET.The continuous integration server I’m using is CruiseControl.NET which will currently be running in the background as a service on my development machine.

Clover.NET proved to be the most difficult to wire-in, but this was down to it not being entirely clear which build of CloverNAnt to use, as it happens, it was 0.85.2053. A more recent build (2100) I believe is to fix breaking changes in 0.85rc3+ builds.

Firstly, we load information from CloverNAnt’s assemblies:

This ensures we don’t need to copy the assembly over to NAnt’s directory. The current Subversion repository for the project has both NAnt and NAntContrib under source control – a practice I’ve seen recommended in a few places, including John Robbins’ excellent so this keeps everything nice and clean and tidy.

Clover.NET works by instrumenting the code before compilation, writing in additional instructions to generate a database of results during execution. So, before compilation, we use the following tasks:

/tests//”/> <mkdir dir=”${tests.dir}” unless=”${directory::exists(tests.dir)}” />

Since the clover-setup task **doesn’t automatically create the CloverBuild folder (where it temporarily writes instrumented code to) it’s necessary to create the directory first. The exclusion mask ensures that we don’t instrument (and thefore check coverage) of the test fixtures themselves – just the classes under test. The other thing of note is the final line – CloverNAnt relies on the CloverRuntime assembly to work, and for our tests to run, we’ll need to have the CloverRuntime assembly in the same path. Since all test assemblies are written to the same folder, we just need the one location. Once that’s been done it’s time to execute the tests as normal, and produce the coverage report.

Since this is already long enough (and has taken longer than expected to write) I’ll save the Continuous Integration aspect of the build system for the next post!