Verifying validity of Workflow Service in Unit Test

Introduction

At work we’ve been having a little bit of trouble verifying that a Workflow Service still “works” after we change something. This is because our custom activities are in a separate assembly. When we change the activities and run MSBuild, we’ll notice that the unit tests still work and that the workflow still compiles. Only after we deploy the service and try to hit it, do we see errors that indicate that the workflow can not be instantiated, for instance because we removed a parameter from an activity. We need some kind of regression testing to prevent this.

To solve this, we now instantiate the workflow in a Unit Test as I will describe in this post.

Problem description

Suppose I have a very simple CodeActivity that takes two values and multiplies them:

public sealed class CodeActivity1 : CodeActivity
{
    public InArgument Input { get; set; }
    public InArgument Factor { get; set; }
    public OutArgument Result { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
        var input = Input.Get(context);
        var factor = Factor.Get(context);

        var result = input*factor;

        Result.Set(context, result);
    }
}

I then have a Workflow Service which calls this activity with a value for Input that it gets from a service call, and a constant value of 3 for the Factor:

workflowservice1

So far so good. Now let us say that some team member decides to change the activity, and removes the Factor parameter:

public sealed class CodeActivity1 : CodeActivity
{
    public InArgument Input { get; set; }
    public OutArgument Result { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
        var input = Input.Get(context);
        var factor = 2;

        var result = input*factor;

        Result.Set(context, result);
    }
}

We run the nightly build and all is in order, since nobody opened the workflow in the designer. Doing so would have pointed out the following error, which does not show up during build:

workflowservice2

There is also an error in the error list of Visual Studio:
Could not find member ‘Factor’ in type “WorkflowCompilation.CodeActivity1”.

The important point here is that, because Workflow services are only compiled when they are called, we would not have noticed this error if we had not opened the Workflow in designer. Since in our current setup we use a shared assembly for activities, we generally do not want to have to manually open all the solutions that rely on this assembly to see if we have broken anything.

The solution

To detect these kinds of issues before we deploy our services and let our test team figure out nothing works anymore, we write a unit test that attempts to instantiate the workflow:

[TestClass]
public class WorkflowUnitTests
{
    [TestMethod]
    public void Test_WorkflowCanBeInstantiated_Succes()
    {
        var xamlReaderSettings = new XamlXmlReaderSettings 
        { 
            LocalAssembly = typeof (CodeActivity1).Assembly 
        };
        var xamlReader = 
            new XamlXmlReader(@"..\..\..\WorkflowCompilation\Service1.xamlx", xamlReaderSettings);
        object xamlServiceImplementation = XamlServices.Load(xamlReader);
        var workflowService = xamlServiceImplementation as WorkflowService;
            
        Assert.IsNotNull(workflowService);
    }
}

Note that I had to get a reference to the assembly that the Workflow Service is in. In my example project this was the same as the CodeActivty1 assembly, but in reality I will have to get the assembly reference some other way. I need this reference because I am trying to instantiate the workflow from another assembly than the one it is defined in, else this line in the Xaml won’t work:

xmlns:w="clr-namespace:WorkflowCompilation;assembly=WorkflowCompilation"

Running the unit test produces the desired result: it will fail with this message:
Test method UnitTestProject1.WorkflowUnitTests.Test_WorkflowCanBeInstantiated_Succes threw exception: System.Xaml.XamlObjectWriterException: Cannot set unknown member ‘WorkflowCompilation.CodeActivity1.Factor’.

Conclusion

With this method in place, we can now modify our activities as we like and all we have to do to verify any workflow depending on them is to run the automated build process. Of course we still have to update the affected workflows, but we can now do so before deploying to the test environment.

Was this useful to you, or do you have suggestions to improve it? Feel free to let me know in the comments!

1 thought on “Verifying validity of Workflow Service in Unit Test

Leave a Reply to Broekhaas Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.