Tuesday, March 23, 2010

AppDomain.CurrentDomain.BaseDirectory and MSTest

I have become a big fan of using XML files to store lists of data. Specifically when that data is to be displayed via the presentation layer of my application(s). While writing an extremely simple unit test just to verify that it works I discovered what I thought to be a crucially bad design to MSTest:

AppDomain.CurrentDomain.BaseDirectory returns the directory where your assemblies are copied during test execution, not the "real" base directory.

Let's look at an example.

I have a class BaseDocumentLocater that attempts to retrieve an XML file and an associated XSD file from AppDomain.CurrentDomain.BaseDirectory. The files are marked as Content and are always copied to the output directory (ie. bin if your running in the visual studio web server or IIS). Assuming that your application lives in C:\Source\MyApp then your runtime AppDomain.CurrentDomain.BaseDirectory would be C:\Source\MyApp\bin.

However, when you're running MSTest then your BaseDirectory would be something like this:

C:\Builds\MyApp CI Build\{builder number}

This wouldn't be an issue except for the fact that only dlls, pdbs, and config files are copied to this directory. This means that my XML / XSD files wouldn't exist when BaseDocumentLocator tries to locate them in AppDomain.CurrentDomain.BaseDirectory\{fileName}.

Needless to say I thought this was quite perplexing and a really terrible design. I googled and binged and even yahoo'd for several hours. I mulled over every setting that I could find and nothing seemed to present itself. I actually got to the point of attempting to set BaseDirectory in my unit test! Right before I got officially fed up and turn in for the night I noticed that my application had no testsettings document. I decided to add one and check out the settings. To my dismay there was nothing in there that seemed to offer a solution. Being the good little Test Driven Developer that I am I ran all of my tests one last time and auto-magically the tests passed! BaseDocumentLocator found the XML files! I thought this was very odd to say the least. I debugged the unit tests in question and my jaw nearly hit my desk when I saw the value of BaseDirectory was back to the bin folder! WTF?! Was I going crazy? I hadn't been drinking. I know that these tests were failing but all seemed to be working now. On a hunch I deleted the testsettings file and re-ran the tests. They failed. BaseDirectory was now the returning the build directory again. Needless to say, adding the testsettings file again resolved the issue.

The point of this post is to save some poor schmuck a few hours of pounding his or her head on their desk if and when this issue presents itself. Are you that schmuck?