While the xpath function in a BizTalk orchestration is a very powerful feature I have often come across the situation where someone has hard coded an xpath expression in an orchestration.
If you have read some of my previous posts about testing I've tried to get across the general theme like test-driven or test-assisted development approaches where the underlying principle is that your building up your solution of small well tested units that are put together and the resulting solution is usually quite robust. You will be finding more bugs within your unit tests and fewer outside of your team.
The thing I don't like about the xpath functions usual usage is when you come across an orchestration which has something like the below snippet in an expression or assign shape:
string result = xpath(myMessage,"string(//Order/OrderItem/ProductName)");
My main issue with this is that the xpath statement is hard coded in the orchestration and you don't really know it works until you are running the orchestration. Some of the problems I think you end up with are:
Approach to Testing
The technique I usually follow is to hold the xpath statement as a constant in a helper class or to format a constant with a helper function to get the actual xpath statement. It is then used by the orchestration like follows.
string result = xpath(myMessage, MyHelperClass.ProductNameXPathStatement);
This means that because the xpath statement is available outside of the orchestration it now becomes testable in its own right. This means:
I'm now able to implement some testing around my xpath statements which usually are something like the following:
- The test will use a sample xml file
- The sample will be validated against the schema
The test will execute the xpath statement and then check the results are as expected
BizTalk uses the XPathNavigator internally behind the xpath function to implement the queries you will usually use using the navigators select or evaluate functions.
In the sample (link at bottom) I have a small solution which contains a schema from which I have generated a sample instance. I will then use this instance as the basis for my tests.
In the below diagram you can see the helper class which I've encapsulated my xpath expressions in, and some helper functions which will format the expression in the case of a repeating node which would want to inject an index into the xpath query.
I have then created a test class which has some functions to execute some queries against my sample xml file. An example of this is below.
In the test class I have a couple of helper functions which will execute the xpath expressions in a similar way to BizTalk. You could have a proper helper class to do this if you wanted.
You can see now in the BizTalk expression editor I can use these functions alongside the xpath function.
I hope you can see with very little effort you can make your life much easier by testing xpath statements outside of an orchestration rather than using them directly hard coded into the orchestration.
This can also save you lots of pain longer term because your build should break if your schema changes unexpectedly causing these xpath tests to fail where as your tests around the orchestration will be more difficult to troubleshoot and workout the cause of the problem.
The sample is available from the following link:
On the subject of using the xpath function, if you don't already use it the below tool is very useful for creating your xpath statements (thanks BizBert)