Sunday, December 7, 2008

Unit Testing WF Workflows with NUnit

When I looked around for approaches to testing Windows Workflow Foundation workflows, I was surprised at how few examples I found. There is a fair amount of buzz around testing custom activities, but not much on entire workflows. Maybe that's because folks consider testing a complete workflow to be an "integration testing" task rather than a "unit testing" one. As an eternal pragmatist, that is a distinction that I could not possibly care less about if I tried. I mean, you really should be testing your complete workflows to the extent possible, and if your unit testing tools work for that, why not use them? So I set out to create a base class using NUnit which could easily be extended by test fixtures that want to run workflows.

My first cut at this is on my Code Gallery page. The base class is called WorkflowTestFixture. It takes a generic type parameter which is the (sequential) workflow that you want to execute. The resulting test fixture code comes out looking like this:

[TestFixture]
public class
TestMyWorkflow : ScottMcMaster365.WorkflowTestFixture<MyWorkflow>
{
    [Test]
   public void
TestNormalExecution()
   {
      AddArgument(
"AccountNumber", 60005)
;
      Run();
      Assert.AreEqual(20000.00M, GetOutput("AvailableCredit"));
   }
}


AddArgument, Run, and GetOutput are base class methods which set up the workflow's inputs, synchronously execute the workflow, and retrieve output parameters, respectively. The actual implementation of WorkflowTestFixtue<> is nothing special -- in fact, it comes out looking a lot like some of the code that K. Scott Allen posted for testing custom activities. (I'm not sure why Scott didn't create a base class for the stuff that he finds overly verbose. Maybe he did that in a later post that doesn't Google as well.)

Clearly there are some workflows and styles of workflow for which this approach will not work well. Right now I see it as primarily useful for sequential workflows which can execute directly to completion without a lot of external integrations with databases, services, etc. That said, I believe that still constitutes an important class of workflow. As for the limitations, I hope to remove some them in the future. Suggestions are welcome.

No comments: