.NET MSTest and DeploymentItem Attribute

I was recently reminded that order of operation can byte you when trying to troubleshoot intermittent unit test failures.

First, I’ll be the first to admit that if you want to avoid problems with unit testing it’s best to avoid any dependency outside of your actual code base, things like databases, API and even the file system are best avoided in execution of your unit tests. That last one, the file system, in some applications is really hard to avoid.

If you happen to be using MSTest, a helpful attribute for your test is DeploymentItem. This particular attribute allows you to define a file within your unit test project assuming it’s marked as “Copy Always”. With this attribute in place you can then combine this with TestContext.DeploymentDirectory to find this sample file and then do what you need to do.

In my particular case I was having an issue with the unit tests failing on the build machine but not locally. After stumbling around for a bit I finally feel back to the old debugging standard of printing out the entire directory of files to the console. It was at this point that I realized I was able to create files in the expected location so why could I not find the DeploymentItem? The answer, side effects.

In one test I “moved” the resource item, and it had just been a situation where locally the tests “happen” to execute in an order such that the move operation was happening at the end of the test cycle, thus masking the problem. When I switch the test in question to “copy” the file, which was still a valid test mind you my problems went away.

As an alternative approach to solving this problem you could make the file an embedded resource and then, in the arrange part of the test, write out the file to disk and then perform the test to ensure that the file always exists at the start.

I hope this information helps others avoid wasting time with these type of silly order of operation problems.

Comments

Post a Comment

Popular posts from this blog

Using telnet to troubleshoot connectivity.... and watch Star Wars

Example of using LazyInitializer.EnsureInitialized