Unit testing BizTalk artifacts using BizUnit

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:

The test steps also allow for using a 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:

In order to be able to verify the context of a BizTalk message after execution of the pipeline, the test steps allow for using an xml file, that contains the context of the BizTalk message(s).

<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 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>

The ExecuteMapStep, ExecuteReceivePipelineStep and ExecuteSendPipelineStep have been included in BizUnit 3.1, which is now available at codeplex. Thanks, Kevin!

Advertisements

About Bram Veldhoen

I'm an independant senior software development consultant, working mostly in the area of integration using Microsoft BizTalk Server, Windows Communication Foundation and .NET.
This entry was posted in BizTalk and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s