简体   繁体   中英

Good practice for DeploymentItem?

I'm fairly rusty when it comes to C#. I've been poking my nose around internet trying to find a solution to my question without success.

I created a test project using MSTest. Some tests use files, that I added to my project test under the folder TestData, and they are copied when executing the test by using the attribute DeploymentItem.

Example: [DeploymentItem(@"TestData\test.txt")]
This copies test.txt at the execution folder and it works. However, when I want to use this file in the test, I then have to work on "test.txt" instead of @"TestData\test.txt". Thus, if I want to factorize my code, I have to have two variables:

        const string testFileName = "test.txt";
        const string testFilePath = @"TestData\test.txt";

and then use them as

        [DeploymentItem(testFilePath)]
        public void TestFunction()
        {
            [...]testFileName[...]
        }

Ideally, I want instead to write:

        [DeploymentItem(testFilePath)]
        public void TestFunction()
        {
            [...]testFilePath[...]
        }

This way I would only need one variable.

It would work if I use the second argument of DeploymentItem as such:

        const string testFilesFolder = "TestData";
        const string testFilePath = @"TestData\test.txt";

        [DeploymentItem(testFilePath, testFilesFolder)]
        public void TestFunction()
        {
            [...]testFilePath[...]
        }

However, that forces me and everyone to think about passing the second argument every time we use DeploymentItem. But it has the merit of working.

Here are the different things I tried to do to address the issue:

  • Inheriting from DeploymentItem to simply add my own constructor: DeploymentItem is sealed so this is not possible.
  • Creating my own attribute, by copying the code of DeploymentItem. The file is not copied at all:
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
    class DeployFileAttribute : Attribute
    {
        public DeployFileAttribute(string path)
        {
            Path = path;
            OutputDirectory = System.IO.Path.GetDirectoryName(path);
        }

        public string Path { get; }
        public string OutputDirectory { get; }
    }

    [DeployFile(testFilePath)] // testFilePath is not copied at all, even though the constructor is correctly executed.
  • Creating a method that would return the attribute. It does not seem like it is possible to use the result of a method as an attribute:
        public static DeploymentItemAttribute DeployFile(string path)
        {
            return new DeploymentItemAttribute(path, System.IO.Path.GetDirectoryName(path));
        } // No compilation error

        [DeployFile(testFilePath)] // DeployFileAttribute type does not exist
  • Creating something like a C++ style using statement or C style macro, I can't seem to find a syntax that works
        using DeployFile(string toto) = DeploymentItemAttribute(toto, System.IO.Path.GetDirectoryName(path)); // Syntax is wrong, could not find one that works

Any hindsight would be welcome!

From my point of view, there are only two possibilities:

  1. You use DeploymentItem in the way it was created by Microsoft.

    • [DeploymentItem(testFilePath, testFilesFolder)] as you manshioned in your post

    • You can combine source path:

       const string testFileName = "test.txt"; [DeploymentItem(@"TestData\" + testFileName)] public void TestFunction() { [...]testFileName[...] }

      In this case, you'll have just one variable:)

  2. You can write your own extension for MSTest and create an attribute you need. But this is not the easy way. As key words for this approach, you could google for TestExtensionExecution , ITestMethodInvoker and TestClassExtensionAttribute

On the other hand, this is very understandable, why DeploymentItem is implemented as it is. Do not forget, that the source folder can be an absolute path as well. So assume, that you have the following attribute [DeploymentItem(@"S:\Shared\TestFiles\AAA\BBB\test.txt")] What should be the destination folder? But even with relative paths: [DeploymentItem(@"..\..\..\TestFiles\AAA\BBB\test.txt")] - can say the name of the destination folder in this case?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM