Search code examples
c#visual-studiounit-testingmstest

C# Visual Studio run unit tests conditionally


I've to unit test some library features involving SSH communication with both Linux and Windows servers.

I have a test_config.json file provided by the user. This config mainly contains two properties:

public ServerConfig? TestServerLinux { get; set; }
public ServerConfig? TestServerWindows { get; set; }

And here is the problem I'm facing: these tests will only be run locally, not in any pipeline and as this test Windows server is a real machine, the Linux one will be probably launched as Docker Container on dev machine.

All of my test classes will be split to Windows and Linux or contains separate test methods for Windows and Linux. I want the test for each to be run conditionally only if config of that server is filled.

So, if Windows server config is null all TestClasses (or TestMethods) for Windows should not be run.

Is something like that possible using Microsoft.VisualStudio.TestTools.UnitTesting, we have all tests written for that framework so I don't want to introduce another one?


Solution

  • From the answer: How to skip a Unit Test at runtime?

    You can extend TestMethodAttribute. Select the method to run based on the name or read the config file, then return true or false.

    public class TestMethodForConfigAttribute : TestMethodAttribute
    {
        public string Name { get; set; }
    
        public TestMethodForConfigAttribute(string name)
        {
            Name = name;
        }
    
        public override TestResult[] Execute(ITestMethod testMethod)
        {
            if (IsConfigEnabled(Name))
            {
                return base.Execute(testMethod);
            }
            else
            {
                return new TestResult[] { new TestResult { Outcome = UnitTestOutcome.Inconclusive } };
            }
        }
    
        public static bool IsConfigEnabled(string name)
        {
         if (name == "Windows")
         return true;
         else
         return false;
        }
    }
    

    Test method

    [TestClass]
    public class UnitTest1
    {
        [TestMethodForConfig("Windows")]
        public void MyTest()
        {
            //...
        }
    }