PipelineTesting 1.1 Released
I'm please to announce the release of Version 1.1 of my PipelineTesting library for BizTalk Server 2006. PipelineTesting can be used with your favorite unit testing framework to create automated, repeatable tests for the following BizTalk artifacts:
- Custom Pipeline Components
- Custom Pipelines
- XML and Flat File Schemas
Version 1.1 adds the following features:
- Improved XML documentation (it actually builds the XML documents without warnings!)
- Bug fixes
- A new, streamlined and more intuitive API, which also includes wrappers for easy configuration of standard XML and Flat File assembler and disassembler components. The original API is still available, for backwards compatibility.
As usual, the library can be downloaded here. The package includes all source code for the library itself and its unit tests, and a pre-compiled binary and XML doc comments file.
Using the library
To use the library, you need to reference the following assemblies:
- Winterdom.BizTalk.PipelineTesting.dll
- Microsoft.BizTalk.Pipeline.dll
- Microsoft.BizTalk.Pipeline.Components.dll
You will need to include the following namespaces:
using Winterdom.BizTalk.PipelineTesting;
using Winterdom.BizTalk.PipelineTesting.Simple;
Introduction to the API
I won't cover all the API, however, let me introduce the basic mechanics of how the library can be used.
The general way in which the library is used is:
- Create a send or receive pipeline. Pipelines are represented in the API as instances of either the ReceivePipelineWrapper or SendPipelineWrapper classes.
PipelineTesting provides ways to create an instance of a pre-compiled BizTalk pipeline (including the built-in pipelines in BizTalk), or creating an empty pipeline. - Configure the pipeline, by adding any components you require (if needed) in the proper stages of the pipeline, as well as providing it with any document specifications (schemas) that will be required by assembler or disassembler components in the pipelines.
This allows the library to run completely independent of your BizTalk configuration, so you don't even need to deploy your stuff to the server before taking advantage of the library; providing a very quick feedback cycle! - Create input messages to provide to the library. You can create messages with any shape or characteristics that BizTalk allows, such as multi-part messages, adding context properties and so on.
- Execute the pipeline: Just pass in the input messages and validate the resulting messages!
Example: A simple XML Send Pipeline
The following example shows how to create a standard XMLTransmit pipeline, provide a schema to use and execute the pipeline with an input message:
string msgBody = "...";
SendPipelineWrapper pipeline = Pipelines.Xml.Send()
.WithSpec<Schema1_NPP>();
IBaseMessage output = pipeline.Execute(
MessageHelper.CreateFromString(msgBody)
);
Example: Batching messages in a Send Pipeline
Here's a more interesting test for a send pipeline. This one will create an empty Send pipeline, add a standard XML Assembler component to it, configured with an Envelope and a Document schema and then feed multiple input messages to be assembled into a single one, encoded with S/MIME:
XmlAssembler xml = Assembler.Xml()
.WithDocumentSpec<SimpleBody>()
.WithEnvelopeSpec<SimpleEnv>();
SendPipelineWrapper pipeline = Pipelines.Send()
.WithAssembler(xml)
.WithEncoder(new MIME_SMIME_Encoder());
// Create the input message to pass through the pipeline
string body =
"<o:Body xmlns:o='http://SampleSchemas.SimpleBody'>"
+ "this is a body</o:Body>";
// Execute the pipeline, and check the output
// we get a single message batched with all the
// messages grouped into the envelope's body
IBaseMessage outputMessage = pipeline.Execute(
MessageHelper.CreateFromString(body),
MessageHelper.CreateFromString(body),
MessageHelper.CreateFromString(body)
);
Assert.IsNotNull(outputMessage);
Notice that, in this example, we didn't explicitly add the schemas to the pipeline itself; that's because when they are configured on the XML assembler, the pipeline picks it up automatically.
Example: Parse a flat file
In this example, I'll create a new receive pipeline and add a Flat File disassembler to it to parse a flat file from a BizTalk schema:
FFDisassembler ff = Disassembler.FlatFile()
.WithDocumentSpec<Schema3_FF>();
ReceivePipelineWrapper pipeline = Pipelines.Receive()
.WithDisassembler(ff);
IBaseMessage input = MessageHelper.CreateFromStream(
DocLoader.LoadStream("CSV_FF_RecvInput.txt")
);
MessageCollection output = pipeline.Execute(input);
Assert.AreEqual(1, output.Count);
Conclusion
This brief introduction should give you an idea of the capabilities of the PipelineTesting library. As you can see, the new API is fairly intuitive and simple to use and everyone should be able to use it with minimal effort.
If you have any questions, comments or run into a bug, do let me know; I'll do my best to answer and fix any issues!






Hi Tomas,
Really great testing utility. I plan to use it extensively. I did run into a small bug though. I am trying ot unit test a simple XML disassembler component and am using basically the following code to create my message:
MessageHelper.CreateFromString("<root><order></order></root>")
Everything works well except in my disassembler code, I use an XmlTextReader() to do some work on the incoming message. It fails loading the message as the IBaseMessage Arrives like this:
< r o o t > < o r d e r > < / o r d e r > < / r o o t >
This appears to be due to the CreateFromString method using Unicode to get the byte content. I remedied this by adding an overload that allows for specifying the encoding to use on message creation.
CreateFromString(string body, Encoding encoding)
In the integration tests, I can simply add the appropriate decoder component to the pipeline and avoid having to worry about the encoding.
Again, Thanks for a really useful utility
Chris,
First of all, thanks for the kind words; it’s great to know of other people using it. If you have other improvement requests do let me know!
As for your specific issue; yes, it is correct to say that I’m forcing UTF-16 encoding when creating a message from a string; and to be honest, it was intentional. The class does the right thing, actually and also sets the Charset property of the Body Part according to the spec; and that’s why it works perfectly with the standard disassemblers.
If you’re writing a custom disassembler, then you should *definitely* be using the Charset property to find out what the encoding of the message is (if it’s not present, use a sensible default like UTF-8).
I spent 45 minutes trying to the out-of-the-box pipeline test components working for and got nowhere. Downloaded YOUR bits, and accurately tested my pipeline in about 10 minutes. You my friend, are the hero of the day.
Thanks for the kind words, Richard; glad it was useful
Do let me know if you run into any issues or have any feature requests.
[...] and executed. That’s exactly where Winterdom Pipeline Testing Framework enters in scene; see (Restrepo, 2007) for more details. Winterdom Pipeline Testing Framework will provide support to execute pipelines as [...]