This post discusses writing unit tests against Windows Workflow Foundation rules outside of the workflow runtime. I had to do this for a project recently and didn’t find very many good resources on the net, so hopefully someone will find this useful. See the notes at the bottom of this post that discuss why unit testing rules may not be a good idea.
I am loading the RuleDefinitions into an object in the unit test constructor. I'm doing this work in the constructor because the rules don’t change during execution and I don’t want to incur this overhead during every test execution.
private RuleDefinitions ruleSetDefinitions;
WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
// The rules are embedded into the DLL, so I’m just reading the resource stream
Stream rulesResource = Assembly.GetAssembly(typeof(MyWorkflowClass)).GetManifestResourceStream("MyWorkflowClass.rules");
XmlReader reader = XmlReader.Create(rulesResource);
ruleSetDefinitions = serializer.Deserialize(reader) as RuleDefinitions;
I created a method to run the rules and report any exceptions. This method is really just a helper so I don’t have this embedded into all of my test methods. Notice how I’m using LINQ to query the RuleSetDefinition for the RuleSet I would like to execute; the more I use LINQ, the more I like it
public void RunRuleSet(MyWorkflowClass workflow, string ruleSetName)
var rules = from rs in ruleSetDefinitions.RuleSets
where rs.Name == ruleSetName
RuleSet ruleset = rules.First<RuleSet>();
RuleValidation validation = new RuleValidation(typeof(MyWorkflowClass), null);
RuleExecution execution = new RuleExecution(validation, workflow);
if(validation.Errors.Count > 0)
Finally, I can run the tests against the RuleSet like this:
MyWorkflowClass wf = new MyWorkflowClass();
// Do any setup of the workflow; setting variables, etc
// Perform any assertions to make sure the rule worked as expected
It's very easy to run rules outside of the Workflow Foundation runtime. I found it nice because I could test individual rules easily. But, this could be very useful for applications that need to load rules files at runtime and allow someone to change the rules outside of typical “code”.
Let the buyer beware
Running unit tests against your rules may or may not be a good idea. I totally agree with everything Mike says about it. In general, you want to be very careful about unit testing rules because they are so easy to change and it can be very difficult to write the tests correctly (especially when you get into chaining and re-evaluation).
In my situation, I had some state regulations that needed to be followed so I decided the rules were worthy of unit tests. The major reasons for this decision are the fact that the rules won’t change frequently and the consequences of the rules being wrong were fairly severe.