Continuing the series of posts about testing for BizTalk, this post will discuss our approach to testing Maps. Again like with schema the normal approach used for testing maps is to use the Visual Studio menu to test the map with different instances against the map. In my opinion this approach has some limitations:
1. It needs to be done manually and can not easily be automated
2. The output from the map is normally only validated by the developers eye
3. Changes to the map may not be regression tested effectively
Aim of our approach
In our approach to testing maps the aim is as follows:
1. For each test case for the map we will have an input message and an expected file which is exactly how the output from the map should look. The test will compare the output with this expected result
2. We will develop MsTest/Nunit style tests which will execute the maps
3. The tests will be ran as part of a continuous integration process
The aim is that by testing the maps thourghly outside of BizTalk we know they will work before they are used within a larger process where defects are more difficult to identify.
In the example (available below) I have created a small solution which contains a simple map based on two schemas. The map will use a helper component developed in C#. The helper component is there to demonstrate how to make your maps run outside of BizTalk when they use external assemblies.
The key points of the sample are as follows:
1. The utilities project has an msbuild task that will GAC the assembly during the build. This ensures it is available for use by the map.
2. The test project uses the MapTestingHelper class which wraps up the interaction with the map
3. The test project will reference the maps project from where you can access the maps as a class which derives from TransformBase
The following picture demonstrates the code sample for a test method which will test a map:
In the sample you can see we have the paths to the input, output and expected file. we then have 2 choices of method to call on the MapTestingHelper. We can use:
- ExecuteInMemory - Which uses the traditional way of mapping by passing in the input as an XPathDocument
- ExecuteMapScalable - Which uses the scalable transform method of the BtsXsltTransform class. This is recommended for larger input files
You can also see above that I pass in an instance of the Input_To_Output class which is the map from within the Maps assembly.
When the map has been executed the Helper class also provides a ValidateMapOutput method which you can provide the output and expected file paths. This method will then compare the two files to identify where there may be any differences.
I developed the sample on a BizTalk 2006 R2 machine. I think the signature of the BtsXsltTransform class has changed between versions as to get the helper to work on a standard BizTalk 2006 (non R2) machine I had to change the transform line within the helper to the below signature.
mapInstance.StreamingTransform.Transform(inputStream, mapInstance.TransformArgs, outputStream, resolver);