Search code examples
c#visual-studio-2010unit-testingslowcheetahxslt

Using xml transformations in unit tests


Background:

Currently we have around 10 unit/integration test projects that hit a database to do tests. Each test class that hits the database inherits from a class called IntegrationTest which is in a seperate dll called TestBase. TestBase contains a configuration file (nhibernate_log4net.cfg.xml) that houses the connection string to the database.

Our development team is a group of about 7 or 8. If two team members were to run the unit tests at the same time there would be conflicts because a lot of the tests are adding and deleting data that is common across many tests. This would cause tests to fail erroneously between the two developers.

Layout:

TestBase.dll
IntegrationTest.cs (Contains [DeploymentItem("nhibernate_log4net.cfg.xml"])
nhibernate_log4net.cfg.xml
nhibernate_log4net.cfg.Developer 1.xml (Transformation file)
nhibernate_log4net.cfg.Developer 2.xml (Transformation file)
...

UnitTest.dll
References -> TestBase.dll
MyUnitTest.cs (Inherits from IntegrationTest in TestBase.dll)

Problem:

My idea was to use SlowCheetah xml transformations on the configuration file in the TestBase dll for each developer in the team but the transformed file does not get copied to the Out directory of the unit test. The base configuration file (non transformed one) is the one that gets copied out to the Out directory. I have a feeling it's because of the [DeploymentItem("nhibernate_log4net.cfg.xml") attribute I have to use to get the config file out there in the first place.

Is there any way to use xml transformations on an xml config file that is included in a separate dll than the unit testing project?


Solution

  • You can manually run the transforms by calling a target from msbuild, as outlined here: http://sedodream.com/2010/04/26/ConfigTransformationsOutsideOfWebAppBuilds.aspx

    UPDATE

    I have been able to reproduce your problem. It's subtle but I think it's working as expected. Here's what's happening:

    • The config transform is being applied. The transformed file is placed in the TestBase output directory.
    • You've specified *[DeploymentItem("nhibernate_log4net.cfg.xml")]* in your tests but this fails because the file is not relative to the UnitTest project. To compensate, you marked your config file with the "Copy Local"=true
    • The "Copy Local" ensures that the content from TestBase project is copied to the UnitTest project, but it's either copying the pre-transformed file from the source location or it's moving the file in the bin folder before the XmlTransform task runs. (I'm inclined to think it's the former)

    Few suggestions to address this:

    1. Move the config file to the UnitTest library and apply the transforms there, this will ensure that the config is readily available to the test runner as intended; or

    2. Configure the deployment options in the TestSettings file (instead of the DeploymentItemAttribute) to copy the generated file from the TestBase folder. (<Solution Directory>\TestBase\bin\Debug\cfg.xml); or

    3. Change your projects so that they all share the same Output directory. This will ensure that the DeploymentItem attribute will copy the transformed TestBase configuration file to the TestRun folder. (Incidentally, a shared output folder is a great way to speed up your build because dependencies and content do not need to be copied again and again)

    (Also, mad props out to @SayedIbrahimHashimi who is one of the main contributors behind SlowCheetahXml -- big fan, dig this extension a lot)