Michael Stephenson

keeping your feet on premise while your heads in the cloud
posts - 352 , comments - 407 , trackbacks - 11

My Links

News

View Michael Stephenson's profile on BizTalk Blog Doc View Michael Stephenson's profile on LinkedIn

Twitter












Archives

Post Categories

Image Galleries

BizTalk

Mates

Developing BizTalk Rules the BDD way

Recently we have been looking at changing the way we develop and test BizTalk Business Rules to use a BDD approach and our tool of choice to help with this is Specflow. I wanted to talk through how we do this and also why I think its useful.

I feel Business Rules are an excellent candidate for the BDD style approach to development that Specflow encourages.

It also promotes a TDD style where you can work with your BA to nicely document your rule requirements as you test and implement them. Some of the benefits offered by Specflow include:

  • The specflow test can act as scenario based documentation over how the rule is supposed to work
  • The documentation would be tested and therefore always accurate as part of your ALM process
  • The specflow test makes it much easier to maintain the rule

Ive blogged many times about the various benefits of specflow so lets look at a walk-through of this way of working.

The Specflow Feature File

First off I go into my Visual Studio solution and in an MsTest project and add the configuration to tell Specflow that I am using MsTest in Visual Studio 2010.

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<configSections>

<section name="specFlow" type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow"/>

</configSections>

<specFlow>

<unitTestProvider name="MsTest.2010" />

</specFlow>

</configuration>

 

Next I add a Specflow feature file.

Once I have my new feature I can begin working with my business analyst to document the desired rule behaviour. In the example below we are looking at a business rule which is used to evaluate an employees performance to decide if they should be awarded a promotion. The Gherkin for this looks something like the below:

Feature: Employee Promotion Rules

    In order to manage staff promotions

    As a hr manager

    I want to be able to calculate if an employee should be promoted or not

 

Scenario: Level 4 Employee should not be promoted regardless of score

    Given I have an employee called Joe

    And the employees current level is Level 4

    And the employees current performance is 100

    When The employees apraisal is evaluated by the promotion rules

    Then the employees appraisal score should be 100

    And the employee should not be recommended for promotion

 

Scenario: Level 1 Employee should not be promoted

    Given I have an employee called Joe

    And the employees current level is Level 1

    And the employees current performance is 25

    When The employees apraisal is evaluated by the promotion rules

    Then the employees appraisal score should be 25

    And the employee should not be recommended for promotion

 

Scenario: Level 1 Employee should promoted

    Given I have an employee called Joe

    And the employees current level is Level 1

    And the employees current performance is 26

    When The employees apraisal is evaluated by the promotion rules

    Then the employees appraisal score should be 26

    And the employee should be recommended for promotion

 

Scenario: Level 2 Employee should not be promoted

    Given I have an employee called Joe

    And the employees current level is Level 2

    And the employees current performance is 50

    When The employees apraisal is evaluated by the promotion rules

    Then the employees appraisal score should be 50

    And the employee should not be recommended for promotion

 

Scenario: Level 2 Employee should promoted

    Given I have an employee called Joe

    And the employees current level is Level 2

    And the employees current performance is 51

    When The employees apraisal is evaluated by the promotion rules

    Then the employees appraisal score should be 51

    And the employee should be recommended for promotion

 

Scenario: Level 3 Employee should not be promoted

    Given I have an employee called Joe

    And the employees current level is Level 3

    And the employees current performance is 75

    When The employees apraisal is evaluated by the promotion rules

    Then the employees appraisal score should be 75

    And the employee should not be recommended for promotion

 

Scenario: Level 3 Employee should promoted

    Given I have an employee called Joe

    And the employees current level is Level 3

    And the employees current performance is 76

    When The employees apraisal is evaluated by the promotion rules

    Then the employees appraisal score should be 76

    And the employee should be recommended for promotion

 

 

 

 

As you can see from the above it is very obvious what the expected behaviour should be from this rule which means I can be quite clear what I am supposed to develop. Also if you imagine that we completed the project and left it for 6 months then came back to it we could easily see what the rule is supposed to do.

Implementing the test behind the feature file

The next step is to implement the C# code which will be executed by the specflow test. In the code snippet below you can see the code which I have put into a C# file which the Specflow test will execute based on the given/when/then attribute usage. One of the things you may note is the use of wild cards in Specflow which make it easy to reuse the same step method to execute multiple gherkin statements. An example of this is in the GivenTheEmployeesCurrentLevelIs method where the wild card is used so that we can pass in the level from the gherkin in the feature file.

In the sample we have a simple employee and employee appraisal object which are populated with some data then ran through the business rule policy which will evaluate conditions and then amend the objects accordingly. After the policy is executed the test will make some assertions about how the objects should have been changed.

using TechTalk.SpecFlow;

using Acme.SpecFlow.BRETests.Rules.Facts;

using Microsoft.RuleEngine;

using MsTest = Microsoft.VisualStudio.TestTools.UnitTesting;

 

namespace Test

{

[Binding]

public class EmployeePromotionSteps

{

private Employee _employee = new Employee();

private EmployeeAppraisal _appraisal = new EmployeeAppraisal();

 

[Given(@"I have an employee called (.*)")]

public void GivenIHaveAnEmployeeCalled(string name)

{

_employee.Name = name;

}

 

[Given(@"the employees current level is (.*)")]

public void GivenTheEmployeesCurrentLevelIs(string level)

{

_employee.Level = level;

}

 

[Given(@"the employees current performance is (.*)")]

public void GivenTheEmployeesCurrentPerformanceIs(int performance)

{

_employee.CurrentPerformance = performance;

}

 

[Then(@"the employee should not be recommended for promotion")]

public void ThenTheEmployeeShouldNotBeRecommendedForPromotion()

{

MsTest.Assert.IsFalse(_appraisal.RecommendPromotion, "The employee should not be recommended for promotion");

}

 

[Then(@"the employees appraisal score should be (.*)")]

public void ThenTheEmployeesAppraisalScoreShouldBe(int appraisalScore)

{

MsTest.Assert.IsTrue(_appraisal.AppraisalScore == appraisalScore, "The appraisal score is incorrect");

}

 

[Then(@"the employee should be recommended for promotion")]

public void ThenTheEmployeeShouldBeRecommendedForPromotion()

{

MsTest.Assert.IsTrue(_appraisal.RecommendPromotion, "The employee should be recommended for promotion");

}

 

[When(@"The employees apraisal is evaluated by the promotion rules")]

public void WhenTheEmployeesApraisalIsEvaluatedByThePromotionRules()

{

var policy = new Policy("Specflow.EmployeeAppraisal");

var facts = new object[2];

facts[0] = _employee;

facts[1] = _appraisal;

policy.Execute(facts);

policy.Dispose();

}

}

}

 

 

This scenario is a very simple business rule to illustrate the technique but it should be possible to use the approach with any rule you want to develop. If you can test it with C# then you can test it with specflow.

Developing the Rule

At this point we have developed our specification for the behaviour of the rule and also the test cases which should prove the rule works and we can begin using red/green/refactor development techniques to build our rule. Lets start by developing the default rule for the default case.

Default Rule

In the default rule it's a bit like an else clause. Based on the specification of behaviour we will be focusing on the scenario where the employee is not level 2 or 3. We aim to prove that a level 4 employee would not be promoted regardless of their performance score.

The rule would look something like the below picture.

When we have added the implementation to the rule we should now be able to begin executing the test case for the level 4 employee and see that they are not promoted even if they score 100 in their performance. If we make any errors when implementing this rule we can work through these until the test goes green.

 

Adding the Level 1 Employee Rule

When developing the level 1 rule we are now focusing on the two test cases which test the level 1 employee. If we run these tests we will find that the not recommended for promotion test will pass straight away but the recommend for promotion test fails so we will add a new rule to the policy to check that a level 1 employee should be promoted if they score more than 25 points. The rule for this would look something like the below picture.

The two tests we will work with check that the employee is only promoted if they score 25 points or more. We should also rerun the test case for the default rule to make sure out level 4 employee is still not promoted.

 

Adding the Level 2 & 3 Rules

We would then continue to add the rules for the level 2 and 3 employees the same as we did for the level 1 employee ensuring we work through any errors as we add the rules and also check that the other tests still pass.

At the end of the implementation of the rules we may want to revisit the original specflow definition and to see if we need to add any additional scenarios to make sure we have adequately covered things like boundary conditions etc.

 

Conclusion

As you can see once our core cases are in place we are really just reusing the same specflow gherkin statements to add additional test cases and we can end up with a very solid set of test cases for our business rule ensuring that it is thourghly tested in isolation before we start trying to use the rule from within BizTalk which means that we should have no issues calling the rule from an orchestration as we know the rule executes exactly how we expect it too before we use it in our wider solution implementation.

Hopefully you can see combining Specflow with the traditional way of testing business rules from .net code adds a lot of additional value and lowers the cost of ownership of your code without requiring anymore effort.

 

The Sample

The sample is available at the following location: https://s3.amazonaws.com/CSCBlogSamples/SpecFlowBRETest.zip

In the sample you will find the xml file called BRERulePolicy.xml which contains the rule policy used in this example and you can then deploy that and play around with the tests. Please note that there is an msbuild snippet in the C# project which deploys the assembly to the GAC during compile so you may need to modify that to the location for gacutil on your machine.

 

Print | posted on Friday, July 13, 2012 7:41 AM | Filed Under [ BizTalk BizTalk Testing ]

Feedback

No comments posted yet.
Post A Comment
Title:
Name:
Email:
Comment:
Verification:
 
 

Powered by: