MSTest VS2010 - DeploymentItem copying files to different locations on different machines - c#

I have found that DeploymentItem
[TestClass(), DeploymentItem(#"TestData\")]
is not copying my test data files to the same location when tests are built and run on different machines.
The test data files are copied to the "bin\debug" directory in the test project on my machine, but on my friend's machine they are copied to "TestResults\name_machine YY-MM-DD HH_MM_SS\Out".
The bin\debug directory on my machine can be obtained with the code:
string appDirectory =
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
and the same code will return TestResults\*name_machine YY-MM-DD HH_MM_SS*\Out on my friends PC.
This however isn't really the problem. The problem is that the test data files I have made have a folder structure, and this folder structure is only maintained on my machine when copied to bin\debug, whereas on my friends machine only the files are added to the TestResults\*name_machine YY-MM-DD HH_MM_SS*\Out directory. This means that tests will pass on my machine and fail on his!
Is there a way to ensure that DeploymentItem always copys to the bin\debug folder? Or a way to ensure that the folder structure will be retained when DeploymentItem copies the files to the TestResults\*name_machine YY-MM-DD HH_MM_SS*\Out folder?

After playing around for a while, it looks like the best way to deal with it is to ensure that for every subdirectory, you add a new DeploymentItem making sure that you specify the "outputDirectory", like so:
[TestClass(), DeploymentItem("TestData\\", "TestData"),
DeploymentItem(#"TestData\\SubDir\\", "TestData\\SubDir")]
This allows the tests to run on your machine - hope this helps someone!

Related

C# File Disappeared after FileInfo.MoveTo with Local Path (Windows)

I Ran FileInfo.MoveTo("filename.txt") with just a name instead of passing a full path and the file just disappeared. I believe in linux this would make it go to the root directory "/", but on Windows I'm not sure if there is a such thing as a root directory beyond just C: Is there any way to locate my lost file?
It is likely in the working folder that your executable is running from. For example, MyApp\bin\Debug, depending on the configuration you are running in.
It should be in project folder. Usually files without specefying path are saved there. (in folder with .exe file)

Unit Testing, Current Directory and Application Path

When coding parts of an application that require access to a directory, I often write the code so that if the Directory is specified using a relative path, the system assumes that the intent is to use a directory subordinate to the directory/folder that the Application (Executable) is running in (or was loaded from).
But when I run Unit Tests which exercise this code, it turns out that the Application path is a completely different directory, because the "Application " is the Test runner Harness, and it is running in a separate directory.
For writes this is no problem, but if the code is attempting to read a file configured in the solution as [Content] from a directory that the compiler copied as part of the build process, this file is of course not in the Test Runner version of the folder at all.
This can be resolved for files that are physically in the test project solution space, (by adding additional instructions on TestRunner configuration), but as far as I know, if the file is specified in the Solution as a link to a physical file located outside the project space, then I have yet to be able to find a simple solution to the problem.
What solutions to this issue exist? and what are the pros/cons of each one?

Copying static files from a referenced project to the test deployment directory for unit tests

I'm trying to configure Visual Studio's in-built test runner (msunit) to copy some static files to the output directory, but am so far unsuccessful.
The static files reside in a common test project which all the other test projects reference. The static files have
Build Action: Content
Copy to Output Directory: Copy always
When each test project is built, the static files are copied to the \bin\Debug\ directory, but when the tests run and msunit copies everything to a \TestResults\ directory, these static files are not copied.
Copying the files to the output directory
According to this MSDN page,
To make additional files available during a test, such as test data or
configuration files, incorporate the files into your project and set
the Copy to Output property. If that is not practical, deploy
additional files or directories by using the DeploymentItemAttribute
on test classes or methods.
Taking these two suggestions in turn, the first I've tried without success... or must the static files be in each of the test projects? Is not enough to have them in a referenced project?
And as for the DeploymentItemAttribute, I really don't want to have to put this above every test class in every test project.
Running the tests in their original location
Another option would be to run the tests in their original location rather than deployed to the \TestResults\ directory, which I'd be happy to do if I could figure out how to configure such.
This MSDN page explains how to configure how the tests are run, though despite being the only page where the *.runsettings file is described, it's woefully short on detail. For example, it provides a sample wherein the <TestAdaptersPaths> element contains a dummy value, but doesn't explain what it can be replaced with.
And this *.runsettings file also doesn't explain if it's even possible to run the tests in the original output directory. This is something which is possible with the older *.testsettings file, but the documentation also says that a *.testsettings file may only be used in legacy mode, which is slow and not as robust; and although I may specify a *.testsettings file in the *.runsettings file, I would also then have to force the tests to run in legacy mode.
So it appears to be the case that the older version permitted a configuration setting which indicated that the tests should not be deployed to another directory, but that the new version doesn't support this (or doesn't document that it supports it).
Using xcopy
Here is another MSDN page wherein it is suggested to define a post-build task to xcopy the files into place. I've tried this as well and the files never appear in the deployment directory.
So in summary, everything I've tried has proven unsatisfactory. Could someone please explain how I can tell my test projects to copy static files from a referenced project into the deployment output directory (preferable), or how I can configure the tests to run in their original location?
Update
I'll also add that if an individual test method is run, the test will run in the standard output directory (that specified in the project's properties, default is "bin\Debug\"). In such a case the test runs as expected because the static files are present in the standard output directory; if multiple tests are run (either choosing "Run all tests" at project or class level) then the tests are run from a uniquely-named deployment directory under the "TestResults\". It is in this latter case where the static files are not copied.
Furthermore, if I decorate a test class with [DeploymentItem("...", "...")] then the specified file is copied, but if I decorate a common class (used for DB setup) with the same attribute (and which is also decorated with [TestClass]) then the specified file is not copied.

How Do I Specify The WEB Test Results Output Folder Name In VS2012 Ultimate

I've read and read and read for days, and I give up. There are articles that tell you how to do this -- almost. Either how to rename a specific results file, or for testing within MSBuild (TONS of these), or changing the ROOT of the file placement folder structure. Those answers are not helpful. I'm testing directly in VS 2012. [SadFace] Google was not my friend this time.
On our test machines, VS 2012 creates test output files at the bottom of a long folder structure. It looks like this (including the files):
<solutionFolder>\
TestResults\
<TestNameFrom.testSettingsFileWithDateAndTime>\
In\
<GuidForThisTestRun>\
<machineName>\
RecordedMedia.trmx
ScreenCapture.wmv
UITestActionLog.html
This file structure is not only unreasonable (as there is no correlation between a test and it's folder) it is also hard to navigate. And there's NOTHING in any of the folders from TestResults on down until the machine name folder. That means we have to navigate three extra folders EVERY TIME we need to look through the test results or forward them to the developers (assuming we can figure out which to look in).
If there are multiple tests in the run, there will be multiple GUIDs in the "In" folder, with a folder named "machine-name" in that, and the test result files in the machine name folder. For example (including the files):
RegressionTesting\
TestResults\
WebRegressionTests _2015-09-23 14_27_20_\
In\
36fe2581-7e14-c3d0-b0fa-1956665ab20d\
DEV0282C\
RecordedMedia.trmx
ScreenCapture.wmv
UITestActionLog.html
e3448182-eb47-1840-cbde-ca5bd5660270\
DEV0282C\
RecordedMedia.trmx
ScreenCapture.wmv
UITestActionLog.html
ed71d0f3-4fc5-42ab-96e3-b68efecdf4d8\
DEV0282C\
RecordedMedia.trmx
ScreenCapture.wmv
UITestActionLog.html
(There's also an "Out" folder, a sibling to "In", but it's always empty.)
What I'd like is to specify the folder structure myself, to include (beside the date and time) the test case name and number (from Microsoft Test Manager), but to EXCLUDE those three empty, unused, useless folder layers. My ideal folder structure looks like this:
Regression\
TestResults\
64105 Delete Bumpuses Dogs 2015-09-23 14_27_20\
RecordedMedia.trmx
ScreenCapture.wmv
UITestActionLog.html
By exploration, I found that TestContext.TestResultsDirectory contains the absolute path to the results folder. I considered trying to set the folder name in code, but TestContext.TestResultsDirectory is read-only. Sad. Would'a been so easy . . .
I've also considered just manually renaming folders and moving files at the end of the test after the browser closes. Problem: The files are (apparently) created in some temp folder somewhere, and are not moved to their documented folders until after the user code has exited.
Here are two of the pages I've read (that's all I'm allowed to post!?!?):
VS2012 Unit Tests: How to change the location of the TestResults folder (Poor Thomans never got an answer to this question. I fear I'll be in the same boat.)
https://msdn.microsoft.com/en-us/library/jj635153.aspx
The name of the folder can be changed via the "Test results names" page in the editor for the .testsettings file. The page can be seen in this image from Visual Studio 2013 Ultimate edition.
I do not know of any way to alter the layout of the directories that hold test results.
The out directory is where files used for the tests are deployed. Depending on the type of test, the files here include .dll, .webtest, .loadtest, .csv (or .xml, etc, as used for data driving) and others.
The in directory holds files generated when running the tests. The names in and out make some sense when viewed from the non-test-execution phases of the work. The outputs of deploying are written to the out directory. The inputs to the analysis of test results are in the in directory.

How can I get "Copy to Output Directory" to work with Unit Tests?

When I build a unit test project before the tests are executed the test output is copied to a TestResults folder and then the tests are executed. The issue I'm having is that not all the files in the Debug/bin directory are copied to the TestResults project.
How can I get a file that is copied to the Debug/bin directory to also be copied to the TestResults folder?
The standard way to do this is by specifying the deployment items in the .testrunconfig file, which can be accessed via the Edit Test Run Configurations item in the Visual Studio Test menu or in the Solution Items folder.
You can specify deployment attribute like an example shown below; Also you need to set "Content" & "Copy if newer" property ( there is no documentation on the later settings, but you have set those to make it work.
[TestMethod]
[DeploymentItem("mytestdata.xml")]
public void UploadTest()
{
}
I had to turn on "Enable Deployment" under Test -> Edit Test Settings -> Local -> Deployment for the [DeploymentItem] attribute to work.
All three answers are correct, depending on your needs.
Adding files to deploy in the .testrunconfig (.testsettings in VS2010) will copy all of those files to every test output folder, even for unrelated tests run in isolation. If you run one test, all the test data files listed in the deployment section of .testssettings will be copied to the test output folder.
In my tests I need to copy an expected XML file to the test output folder to compare with the actual test output XML. I use the DeploymentItem attribute to only copy the XML file related to the test(s) being run. In VS2010 I had to enable deployment in the .testsettings file (but not add any paths) and then reference the XML file path relative to the TestProject in the DeploymentItem.
Hope this helps.
I had a similar problem but mine had to do with pointing to the TraceAndTestImpact.testsettings file instead of the Local.testsettings file. You can change from one to the other under the Test/Select Active Test Settings menu.
The following works in VS2012 for test projects included in multiple solutions without using a testsettings file:
1) Arrange the files and folders you wish to deploy into a folder in the test project directory.
2) In the project properties, create a post build step
xcopy /Y /S /i "$(ProjectDir)<Project_Folder_Name>\*" "$(TargetDir)<Deployment_Folder_Name>"
$(ProjectDir) and $(TargetDir) are macros that will be interpreted by VS and should be included as such.
<Project_Folder_Name> is the name of the folder created in step 1.
<Deployment_Folder_Name> is the name of the folder in which the test files will be deployed and should be named so that it will be unique when multiple test projects are deployed to the same directory, e.g. <Project_Name>_TestInputs.
Test files in shared locations should also be copied to the target directory deployment folder to limit test interactions. Provide the source path relative to the $(ProjectDir) macro. For example "$(ProjectDir)..\..\Common Files\C1219TDL-2008.xml".
3) Add a [DeploymentItem(source, destination)] property to either each test method that uses a deployment file (best practice) or to the test class (easier practice for the lazy or hurried, and the easiest way to update a project the previously used relative paths or a testsettings file).
On a test method, source is the path to the file or directory used in the test method relative to the target directory as created by the xcopy and destination is the path to the directory in which it will be created relative to the deployment directory. So that tests run consistent in either the target directory or a deployment directory. The destination path should be the same as the source path without a file reference. Example: [DeploymentItem("Example_TestInputs\C1219TDL-2008.xml","Example_TestInputs")]. The DeploymentItem should be included on every method that uses that file or directory.
On a class, source and destination are both the name of the folder created in the target directory by the xcopy; this will copy the entire folder to the deployment directory when any test in the class is run. Example: [DeploymentItem("Example_TestInputs","Example_TestInputs")]
4) In the test methods, you can now access files and directories with confidence they will be in the working directory regardless of where Visual Studio has decided to put it that day, e.g. File.Exists(".\Example_TestInputs\C1219TDL-2008.xml").
Would like to just enhance the accepted answer by mentioning a way to get it to deploy specifically for dll's rather then the normal method of using it for data or config etc, for the circumstances where CopyLocal doesn't work:
[DeploymentItem("bin\\release\\iRock.dll")]
[DeploymentItem("bin\\debug\\iRock.dll")]
[TestMethod]
[DeploymentItem("ProjectName/Folder/SubFolder/file.xml", "Folder/Subfolder")]
public void YourTestMethod()
{
// in the method you are testing you should have this:
var filePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase) + "/Folder/Subfolder/file.xml";
}
Try out the Post-Build event command line from within Visual Studio (if you are using that IDE).
In Visual Studio 2012 you don't need a DeploymentItem attribute for the simple case. See my answer here
The accepted answer is correct and so are most of the other answers. However, over the years I have found that the Deploment system of Visual Studio Unit Tests using DeploymentAttribtue and Copy to Output to be cumbersome if you have a large number of data files. I have found that keeping the files in their original location worked better.
Full details in my other answer here.
https://stackoverflow.com/a/53004985/2989655
Hope this helps.

Categories

Resources