77

I can't seem to grasp how MSTest deployment items are supposed to be configured. I have been able to get them working properly by modifying the project's test settings file, but this is less then ideal -- the deployment item configuration is separated from individual tests, and the file paths appear to be stored as absolute paths unless the files are under the solution folder.

Am I not supposed to be able to add a deployment item using the [DeploymentItem] attribute on either a [TestClass] or [TestMethod] without having to create/modify a project test settings file? How do I accomplish this?

(Frankly, I don't understand the need for a separate deployment item configuration -- why not just use the existing 'Copy to Output Directory' settings for project files that should be deployment items?)

7 Answers 7

226

This post here helped me figure out what I needed to do WITHOUT having to manually add items to the .testsettings file.

Step 1 - Enable the MS Test DeploymentItem attribute.

First up, we need to turn on / enable the DeploymentItem attribute.

Go to TEST -> EDIT TEST SETTINGS -> Current Active settings .. eg :: Local (local.testsettings)

alt text

Now goto DEPLOYMENT and make sure Enable Deployment is ticked ON. (By default, it's off).

alt text

Step 2 - Check the File's properties

Now we need to make sure the file which you wish to use in the unit test, is setup to be copied to the BIN directory when you compile. Only files that are in the BIN directory can be used in an MS Test unit test. Why? Because each time an MS Test is ran, it has to make a copy of the sources ... and this means it makes a copy of the current BIN directory files (for the current Configuration).

For example... Current Configuration is Debug (as opposed to Release). alt text

I then add my file ... (take note of the folder structure in the Project)...

alt text

and then make sure this file is ALWAYS copied over to the bin directory when the project is compiled.

alt text

PRO TIP: Copy Always will also work, but always copy the source file over the destination file .. even if they are identical. This is why I prefer Copy if Newer ... but whatever floats your boat

Ok ladies and gents - still with me? Wikid.

When we compile, the file should now exist in the Bin dir....

alt text

Step 3 - Now use the DeploymentItem attribute

Ok, now we can finally use the DeploymentItem attribute in our code. When we do this, this tells the MSTest to copy the file (from the location relative to the bin directory) to the new MS Test directory...

[TestMethod]
[DeploymentItem(@"Test Data\100LogEntries.txt", "Test Data")]
public void Parsing100LogFileEntriesReturnsANewParsedLogEntriesWith100Items()
{
    // Arrange.
    const string fileName = @"Test Data\100LogEntries.txt";
    ILogEntryService logEntryService = new PunkBusterLogEntryService();

    // Act.
    var parsedLogEntries = logEntryService.ParseLogFile(fileName, 0);

    // Assert.
    Assert.IsNotNull(parsedLogEntries);
    Assert.AreEqual(100, parsedLogEntries.LogEntries.Count);
    // Snipped the remaining asserts to cut back on wasting your time.
}

So let's break this down..

[TestMethod]

We all know what that is.

[DeploymentItem(@"Test Data\100LogEntries.txt", "Test Data")]

Starting in the bin directory, go into the Test Data folder and copy the 100LogEntries.txt file to a destination folder Test Data, in the root MS Test output directory which MS Test creates when each and every test is ran.

So this is what my output folder structure looks like (excuse all the mess).

alt text

and voila! we have deployment files, programmatically.

PRO TIP #2 - if you don't use a 2nd string argument in the DeploymentItem attribute, then the file will be copied to the root OUT folder, of the current MS Test.

const string fileName = @"Test Data\100LogEntries.txt";

Now the path to the file is relative to the OUT folder for the current MS Test. As such, I explicitly said to deploy the file into a directory called Test Data ... so I need to make sure I reference that correctly in my code when I want to read in the file.

Just to confirm -> the full path of that filename is translated to something like C:\lots of blah blah blah\My Solution\TestResults\PureKrome_PUREKROME-PC 2011-01-05 23_41_23\Out\Test Data .. for that current MS Test.

9
  • 82
    Although it's a Pegasus. ;-) Commented Oct 7, 2011 at 16:37
  • 20
    OMG! How the hell did i not notice the horn was missing. That's too funny! Cheers Damien :) (I was blinded by the Rainbow .... )
    – Pure.Krome
    Commented Oct 7, 2011 at 20:05
  • This was a lifesaver, really helped me figure this out since VS 2010 wasn't playing nice but ReSharper was when it came to deployment files
    – Urda
    Commented Dec 20, 2011 at 16:02
  • 1
    The docs for DeploymentItem say that relative paths are found starting relative to the "RelativeRootPath" in the testrunconfig or testsettings. By default, this is the Solution folder. Your files are not in "$(SolutionDir)\Test Data". They are in "$(SolutionDir)\Tests\Test Data". Did you change your RelativeRootPath? or are the docs wrong? or is your answer working by some other magic? Commented Nov 29, 2012 at 17:05
  • 3
    @Random - it doesn't work in 2012 because test lists were removed and replaced with TestCategory attributes.
    – Phill
    Commented Mar 21, 2014 at 4:32
15

I thought I'd share a way I ran into problems with MSTest and deployment items. If you Debug/Run your test a 2nd time or more from the "Test Results" window, it uses the settings from a previous run. However, if you Debug/Run the same test from the "Test View" window, it uses the latest settings. I lost an hour to trying to figure out why changes to Local.testsettings weren't being used when I kept starting Debug on the same test from the "Test Results" window.

This is the Test Results window (do not [re]start tests from here after making changes to Local.testsettings):

The Test Results Window

And this is the Test View window (DO start tests from here after making changes to Local.testsettings):

The Test View Window

I hope this saves someone a headache in the future.

1
  • Thank you for this. I've spent so much time restarting Visual Studio before I read this! Commented Dec 18, 2012 at 9:38
7

In Visual Studio 2012 the output directory is the working directory which means that the DeploymentItem attribute isn't needed for the general case (where you don't have specific per-test or per-class deployment items). This means that if you don't need to use the DeploymentItem attribute if there is a set of files that you want all your tests to use or you are not too pernickety about each TestClass/TestMethod having separate deployment dependencies.

You can simply click Project | Show All Files and include the subfolders and files in Visual Studio with the 'Copy always' or 'Copy if newer' attribute to your project and the files will be copied to your output directory with hierarchy intact.

The same applies when running vstest.console.exe from the command line. See here for the details.

Update

There are cases where the default directory will not be the output directory. Specifically when you choose Run All Tests the default path would be under TestResults\Deploy_... The same applies when using a runsettings file or tests use DeploymentItems

The output directory will be the default directory when you are not using DeploymentItems and: -

  • You right click the test(s) in Visual Studio and choose to run / debug, or
  • You run from the command line using vstest.console.exe.
3
  • Not true, in some cases Agent sets working directory same way as VS2010. Do you know how to control this behaviour?
    – Random
    Commented Dec 24, 2013 at 3:35
  • @Random. Did the link help to answer your question? It shows how to run the tests in various ways and from different folders. I am not sure of your specifics, so can't answer for your environment. In my automated build, the tests always run from the output directory, so it seems pretty deterministic in my environment.
    – acarlon
    Commented Dec 24, 2013 at 9:37
  • I went through the link and what I noticed is either I can run tests without testsettings file selected and tests are executed in debug folder so I can use xcopy to deploy or I use testsettings and each run is executed in own folder with a timestamp and neither xcopy nor DeploymentItem work. I tried fixed and relative paths for DeploymentItem and it still fails. Checking "Enable Deployment" in testsettings doesn't affect anything. My setup is pretty vanilla with one difference - I build to x86 and .NET 3.5 (both fixed in all project settings)
    – Random
    Commented Dec 26, 2013 at 3:44
1

If you need separate deployment item in individual test cases then please go ahead and use [DeploymentItem("string file path")] attribute in each test cases.

2
  • 2
    My problem, though, is that the DeploymentItem attribute isn't working.
    – arathorn
    Commented Sep 20, 2010 at 0:59
  • Same here :( I've only ever gotten it working via modifying the settings file.
    – Pure.Krome
    Commented Jan 5, 2011 at 11:53
0

For my case, I add the DeploymentItem attribute, it can't take effect immediately. I have to close and re-open the solution, then the configured DeploymentItem attributes will take effect.

1
  • Actually the downvote wasn't fair. I read the whole tutorial and tried different things, but the solution was: clean the project, rebuild it and then run the tests. Suddenly it all worked :)
    – ecth
    Commented Jul 24, 2018 at 12:31
-1

Looks like this works by default in VS.NET 2012

-1

In VS 2012, All you need is to make the log4net.properties (or whatever config file for log4net ) file Copy if newer. ( right click log4net.properties file to bring up the properties and configure it )

1
  • 1
    The question already has an accepted answer and your answer doesn't provide any additional information. The question isn't even asking about log4net.properties.
    – Guenther
    Commented Sep 15, 2016 at 14:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.