Whipping up a BizUnit test step using the BizUnit 4.0 libraries is a piece of cake, but chances are that any test step you write is going to be used multiple times throughout the life of a project and in ways you can’t predict and you will want to spend the extra effort when developing your test step to cater for this.
BizUnit promotes the reuse of test steps by providing interfaces that allow you to write them in really flexible ways, with the ability to make use of plugins rather than directly implementing logic such as the loading of data or validation of data. This allows for late binding of actual data loader / validator implementations as it is not upto the test step implementor to choose which of these facilities to make use of, but is rather the responsibility of the test case implementor (ie. the person making use of a test step to implement a test).
For example, when writing a test step that calls upon a WCF service, rather than having the test step load its data from a file we can leave the choice wide open so that the test case implementor can choose to load his data from a database, or perhaps read it in from an XML file but run some XPath statements against the message first to adjust its content (making use of the out of the box XmlDataLoader data loader shipped with the BizUnit 4.0 framework).
In this blog post I will list some of the steps I undertook to port Michael Stephenson’s WCF test step for BizUnit 2.0 (many thanks to Michael for writing this fantastically useful step and giving me permission to discuss it) into a BizUnit 4.0 test step while leveraging off the aforementioned features.
Both the old and the new BizUnit test step require some field values to be set such as the WCF input message type name, and the method name etc… The old test step did this by reading the values from the test context as below.
BizUnit 4.0 allows you to programatically instantiate and setup your test steps in a test case, so rather than reading these field values in from the context (one could still do this if required) we can just expose these as public properties, or write a public constructor for the test step class that allows you set these field values.
To make our test step more flexible its a good idea to support for as many substeps as are required to be executed against the response message (if we are dealing with a request-response service, obviously this is not applicable for one-way services). In order to do this we need to instantiate the SubSteps property (defined on the TestStepBase base class) in the test step constructor to ensure that we can add substeps to the collection when we implement our test cases.
We will also want to implement a Validate method in our test step to check that it has been instantiated with all the required and valid field values necessary. This method would be run after the entire test case has been instantiated and is being prepared for execution (ie. after all the individual test steps have been setup and put into their relevant stages in the test case).
On to the meat of test step. Whereas the previous version of the test step had the loading of the file built into the test step itself (loading it from the file system which would be good enough in many cases) we will take it one step further by making use of a generic data loader. Note that the dataLoader is a field which can be set through its corresponding public property or via a constructor (I haven’t allowed for it in my example but there is no reason why you couldn’t setup all your properties in the constructor).
The code to call on the WCF service and optionally consume its response remains largely unchanged. What has been added is the ability to run the optional response through any number of substeps, giving the test case implementor the ability to validate the response in any number of given fashions.
To illustrate how the test step can be used I have created a WCF Service application with a method called GetDataUsingDataContract (yes, I was too lazy to create my WCF service from scratch) which takes in an object of type CompositeType and returns an object of type CompositeType. CompositeType is defined as below, and the method will add up the FirstValue and SecondValue elements and set the value in the Result element before returning the object.
After publishing the WCF Service I created a test project and added a service reference to the published service. I then added references to the BizUnit assemblies as well as my custom test step project. The next step was to create a test method, instantiate the TestCase and the WCFTestStep as below.
Note that the EndPointName is from the name attribute in the endpoint node in the test project’s app.config. If there were multiple endpoints defined in the config then we can choose any of them.
The InputMessageTypeName and the InterfaceTypeName must be fully qualified, the namespaces being based on the service reference, and the application name being the test project itself (or whatever project your service reference is contained in).
The next step was to load the request message from a file, but what I wanted was to be able to replace values in the input file using XPath expressions, thus meaning that I didn’t have to maintain a copy of the input file for each test method. I achieved this using the XmlDataLoader step, replacing the FirstValue element with the value 4, and the SecondValue element with the value 7 in the below example. Note that the format of the input message is based on the type definition in the service reference which might differ slightly from the message definitions you might have used if you were creating your service in BizTalk (e.g. the message you want to submit might have to be wrapped in a parent node), you might want to run the xsd.exe tool against the test project dll to find out how you must format your message. Using a tool such as DanSharp XmlViewer can aid you in creating your XPath statements.
Next up it’s time to implement validation. In the below example I am making use of the XmlValidationStep to validate the response message against its schema (I generated this using the xsd.exe tool), and also to ensure that the value in the Result element is what I was expecting.
Lastly it’s time to add the WCF test step to the test case, to add the test case to a newly instantiated BizUnit object and to execute the test.
If you run the test and view the test result details you get some rather detailed output.
The beauty of the WCF test step is that it should work for any WCF Service regardless of the bindings as long as a service reference has been added which should automatically create the binding and endpoint details in your config file.
If you are interested in downloading the test step you can do so from my google drive. The solution also contains my example WCF Service (which should automatically ask for permission to deploy into IIS when you open the solution), as well as my test project. Let me know if you can think of any improvements to the test step, and once again kudos to Michael Stephenson as most of the implementation logic is based on his pioneering work.