Tuesday, June 09, 2009

Enable Unit Testing in BizTalk 2009

BizTalk 2009 has, for the first time, built-in developer support for testing schemas, maps and pipelines that is available for automated unit testing rather than being hidden behind features in Visual Studio where it can only be used for manual testing.

Anyone interested in finding out more about BizTalk unit testing wouldn't go far wrong looking at Michael Stephenson's series on unit testing http://geekswithblogs.net/michaelstephenson/archive/2008/12/12/127828.aspx

To use or not to use (the unit testing framework)

There has been a debate around the office lately regarding the unit testing features in BizTalk 2009. The debate goes something like this:

1. You don't want to have unit testing enabled on your production assemblies.
2. If you enable unit testing on your assemblies for test and then switch it off for release then you are releasing different (although generated) code.
3. Is the unit testing framework any good anyway?

There has seemed to be a consensus that the unit testing features in BizTalk 2009 aren't that good and we should do without them. However, I beg to differ! Premise #1 - that unit testing should not be enabled on production releases - is I think a false premise.

For example, let's look at unit testing of schemas in more detail. When you enable unit testing you actually change the base class from which your schemas derive, but this base class in turn inherits from the SchemaBase class anyway. All that is added is a method called ValidateInstance which you hook into for your tests - all the rest of the implementation is the same, so to me there is no issue with using this in production code. It means that you can build in release mode and then run your unit tests against your production assemblies to examine their quality which surely should be a good thing!

Remember to set the configurations

When you set your deployment properties on your BizTalk project, you are probably developing in Debug mode, and you might not think to change the deployment settings for release. If you don't explicitly enable unit testing for all configurations or specifically for release then by default your release assemblies will be built without unit testing enabled.

This is something that happened to us today. We are in the first iteration of a project, we've successfully put in a build process right at the start, that build process packages the code into an InstallShield package and installs it onto a Consuinuous Integration environment. We were just getting the build to run the unit and integration tests and publish the results back to examine the build quality and we started getting an error like this when building the test projects:

Cannot implicitly convert type 'XXXX.YYYY.Transforms.CustomerAccount_to_CustomerDetails' to 'Microsoft.BizTalk.TestTools.Mapper.TestableMapBase'

My first reaction was to check that the references in the unit test project were correct - which they were. I had copied the Microsoft.BizTalk.TestTools.dll assembly into a referenced assemblies folder. That was all OK. I then checked to see whether the referenced assembly was available on the build server. It was. In the end the issue was that we were building in Release mode and I had only enabled unit testing in Debug mode. Because of this, my schemas were inheriting from SchemaBase and not TestableSchemaBase and my maps from MapBase and not TestableMapBase etc. Whilst the schemas and maps projects all built OK the build error appeared in the test project.

As soon as I enabled unit testing for all build configurations the schemas then everything built OK and I could go ahead and build my tests.

Test tools not available

This then led quickly onto another issue. The build process always builds in release mode, but it had been set so that unit testing was not enabled. Then when I enabled unit testing the build was OK, and all of the unit tests were passing but we're doing continuous integration so the build process, after the unit tests, includes a deployment step and then a second set of integration tests on the deployed system.

Unfortunately, once the build was making the assemblies testable the deployment script failed (we use InstallShield to put the DLLs onto the file system and then use BTSTask to deploy them into BizTalk as a custom action). BTSTask was failing to deploy the new build because the reference to Microsoft.BizTalk.TestTools could not be resolved. I checked my development machine - it has BTS2009 Developer Edition and Microsoft.BizTalk.TestTools was in the Global Assembly Cache. I then checked the build server, also using developer edition, Microsoft.BizTalk.TestTools was in the GAC on there. I then checked the integration server where we are automatically deploying to - Microsoft.BizTalk.TestTools was missing from the GAC as the developer tools were not installed.

I had to modify the build so that the build tools were deployed into the GAC and then the assemblies would build OK. This goes right back to point #1 above: if the core BizTalk 2009 install does not include the test tools should we be putting them on there anyway or using a different method of unit testing that does not rely on the test tools? On the other hand, if the test tools are there out-of-the-box, shoudn't we be using them?

The debate rumbles on.......

No comments: