First off, credit where credit's due: Tomas Restrepo has done an amazing job making pipeline testing way easier with the pipeline testing library. Read all about it here.
Tomas' library inspired me to write some test steps for the BizUnit framework that would allow for true unit testing of BizTalk components: being able to test BizTalk components without having to deploy the components to a BizTalk server, making testing roundtrips easier and overall less painfull. As additional advantage, you can have all tests use a similar approach/syntax, and use the already present validation steps to validate the results. I have implemented the following steps for BizUnit:
- ExecuteMapStep
- ExecuteReceivePipelineStep
- ExecuteSendPipelineStep
Obviously, the latter two are using Tomas' pipeline testing library.
The ExecuteMapStep step can be used to test biztalk maps, using an input xml file. An example of a BizUnit test, that executes a map and validates the resulting output xml file (via the BizUnit context), is displayed below.
<TestCase testName="T_006_ExecuteMapStepWithValidationWithContextLoader">
<TestExecution>
<TestStep assemblyPath="BizUnit.BizTalkSteps.dll" typeName="BizUnit.BizTalkSteps.ExecuteMapStep">
<Map assemblyPath="..\..\..\Test\BizUnit.BizTalkTestArtifacts\bin\Development\BizUnit.BizTalkTestArtifacts.dll" typeName="BizUnit.BizTalkTestArtifacts.MapSchema1ToSchema2"/>
<Source>..\..\..\Test\BizUnit.BizTalkTestArtifacts\Instances\Schema1.xml</Source>
<Destination>Schema2.006.xml</Destination>
<ContextLoaderStep assemblyPath="" typeName="BizUnit.XmlContextLoader">
<XPath contextKey="testValue">/*[local-name()='Schema2Root' and namespace-uri()='http://BizUnit.BizTalkTestArtifacts.Schema2']/*[local-name()='Child1' and namespace-uri()='']/@*[local-name()='Child1Attribute1' and namespace-uri()='']</XPath>
</ContextLoaderStep>
<ValidationStep assemblyPath="" typeName="BizUnit.ContextValidationStep">
<Context keyName="testValue">1</Context>
</ValidationStep>
</TestStep>
</TestExecution>
</TestCase>
The ExecuteReceivePipelineStep and ExecuteSendPipelineStep let you test receive or send pipelines. The input for both the ExecuteReceivePipelineStep and ExecuteSendPipelineStep (optionally) consists of:
- Per-instance pipeline configuration
- Document specs
- Input xml file (multiple input files can be specified for the ExecuteSendPipelineStep)
- Message context input file(s): an xml file, containing all context properties (name, namespace, value, and whether these properties are promoted or not)
ExecuteReceivePipelineStep:
<TestStep assemblyPath="BizUnit.BizTalkSteps.dll" typeName="BizUnit.BizTalkSteps.ExecuteReceivePipelineStep">
<Pipeline assemblyPath="..\..\..\Test\BizUnit.BizTalkTestArtifacts\bin\Development\BizUnit.BizTalkTestArtifacts.dll" typeName="BizUnit.BizTalkTestArtifacts.ReceivePipeline1">
<InstanceConfigFile>..\..\..\Test\BizUnit.BizTalkSteps.Tests\TestData\ReceivePipeline3.InstanceConfig.xml</InstanceConfigFile>
<DocSpecs>
<DocSpec assemblyPath="..\..\..\Test\BizUnit.BizTalkTestArtifacts\bin\Development\BizUnit.BizTalkTestArtifacts.dll" typeName="BizUnit.BizTalkTestArtifacts.Schema0" />
<DocSpec assemblyPath="..\..\..\Test\BizUnit.BizTalkTestArtifacts\bin\Development\BizUnit.BizTalkTestArtifacts.dll" typeName="BizUnit.BizTalkTestArtifacts.Schema3Env" />
</DocSpecs>
</Pipeline>
<InputContextFile>..\..\..\Test\BizUnit.BizTalkSteps.Tests\TestData\Context.0.xml</InputContextFile>
<Source>..\..\..\Test\BizUnit.BizTalkTestArtifacts\Instances\Schema3Env.xml</Source>
<DestinationFileFormat>Output015.{0}.xml</DestinationFileFormat>
<OutputContextFileFormat>Context015.{0}.xml</OutputContextFileFormat>
</TestStep>
ExecuteSendPipelineStep:
<TestStep assemblyPath="BizUnit.BizTalkSteps.dll" typeName="BizUnit.BizTalkSteps.ExecuteSendPipelineStep">
<Pipeline assemblyPath="..\..\..\Test\BizUnit.BizTalkTestArtifacts\bin\Development\BizUnit.BizTalkTestArtifacts.dll" typeName="BizUnit.BizTalkTestArtifacts.SendPipeline1">
<InstanceConfigFile>..\..\..\Test\BizUnit.BizTalkSteps.Tests\TestData\SendPipeline3.InstanceConfig.xml</InstanceConfigFile>
<DocSpecs>
<DocSpec assemblyPath="..\..\..\Test\BizUnit.BizTalkTestArtifacts\bin\Development\BizUnit.BizTalkTestArtifacts.dll" typeName="BizUnit.BizTalkTestArtifacts.Schema0" />
<DocSpec assemblyPath="..\..\..\Test\BizUnit.BizTalkTestArtifacts\bin\Development\BizUnit.BizTalkTestArtifacts.dll" typeName="BizUnit.BizTalkTestArtifacts.Schema3Env" />
</DocSpecs>
</Pipeline>
<InputContextDir>..\..\..\Test\BizUnit.BizTalkSteps.Tests\TestData</InputContextDir>
<InputContextSearchPattern>Context*.xml</InputContextSearchPattern>
<SourceDir>..\..\..\Test\BizUnit.BizTalkTestArtifacts\Instances\</SourceDir>
<SearchPattern>Child*.xml</SearchPattern>
<Destination>Output.025.xml</Destination>
<OutputContextFile>Context.024.xml</OutputContextFile>
</TestStep>
Per-instance pipeline configuration:
Below the per-instance pipeline configuration of a pipeline, containing only the Xml Disassembler pipeline component.
<?xml version="1.0" encoding="utf-8"?>
<Root xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Stages>
<Stage CategoryId="9d0e4105-4cce-4536-83fa-4a5040674ad6">
<Components>
<Component Name="Microsoft.BizTalk.Component.XmlDasmComp">
<Properties>
<EnvelopeSpecNames vt="8">BizUnit.BizTalkTestArtifacts.Schema3Env</EnvelopeSpecNames>
<EnvelopeSpecTargetNamespaces vt="8">http://BizUnit.BizTalkTestArtifacts.Schema3Env</EnvelopeSpecTargetNamespaces>
<DocumentSpecNames vt="8">BizUnit.BizTalkTestArtifacts.Schema0</DocumentSpecNames>
<DocumentSpecTargetNamespaces vt="8">http://BizUnit.BizTalkTestArtifacts.Schema0</DocumentSpecTargetNamespaces>
<AllowUnrecognizedMessage vt="11">false</AllowUnrecognizedMessage>
<ValidateDocument vt="11">false</ValidateDocument>
<RecoverableInterchangeProcessing vt="11">false</RecoverableInterchangeProcessing>
<HiddenProperties vt="8">EnvelopeSpecTargetNamespaces,DocumentSpecTargetNamespaces</HiddenProperties>
</Properties>
</Component>
</Components>
</Stage>
</Stages>
</Root>
Context xml file:
<MessageInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ContextInfo PropertiesCount="1">
<Property Name="Property1" Namespace="http://BizUnit.BizTalkTestArtifacts.PropertySchema1" Value="10" Promoted="true" />
</ContextInfo>
</MessageInfo>
The code (including tests) have already been uploaded to the owner of BizUnit. I don't know when the next release for BizUnit is planned. If you need the code for these BizUnit steps, send me an email.
The output of the steps consist of:
- Xml output file
- Message context xml file, with the same format as the input context xml file..
The example below displays a BizUnit validation step snippet that checks if a certain property was promoted and has value 10:
<ValidationStep assemblyPath="" typeName="BizUnit.XmlValidationStepEx">
<XPathList>
<XPathValidation query="MessageInfo/ContextInfo/Property[@Name='Property1' and @Namespace='http://BizUnit.BizTalkTestArtifacts.PropertySchema1' and @Promoted='true']/@Value">10</XPathValidation>
</XPathList>
</ValidationStep>
[19-07-2009]: The ExecuteMapStep, ExecuteReceivePipelineStep and ExecuteSendPipelineStep have been included in BizUnit 3.1, which is now available at
codeplex. Thanks, Kevin!