Does MSTest have an equivalent to NUnit's TestCase?

后端 未结 5 427
余生分开走
余生分开走 2020-11-27 15:03

I find the TestCase feature in NUnit quite useful as a quick way to specify test parameters without needing a separate method for each test. Is there anything s

相关标签:
5条回答
  • 2020-11-27 15:21

    MSTest has the DataSource attribute, which will allow you to feed it a database table, csv, xml, etc. I've used it and it works well. I don't know of a way to put the data right above as attributes as in your question, but it's very easy to set up the external data sources and files can be included in the project. I had it running an hour from when I started, and I'm not an automated test expert.

    https://msdn.microsoft.com/en-us/library/ms182527.aspx?f=255&MSPPError=-2147217396 has a full tutorial based on database input.

    http://www.rhyous.com/2015/05/11/row-tests-or-paramerterized-tests-mstest-xml/ has a tutorial based on XML file input.

    0 讨论(0)
  • 2020-11-27 15:24

    I know this is another late answer, but on my team that is locked into using the MS Test framework, we developed a technique that relies only on Anonymous Types to hold an array of test data, and LINQ to loop through and test each row. It requires no additional classes or frameworks, and tends to be fairly easy to read and understand. It's also much easier to implement than the data-driven tests using external files or a connected database.

    For example, say you have an extension method like this:

    public static class Extensions
    {
        /// <summary>
        /// Get the Qtr with optional offset to add or subtract quarters
        /// </summary>
        public static int GetQuarterNumber(this DateTime parmDate, int offset = 0)
        {
            return (int)Math.Ceiling(parmDate.AddMonths(offset * 3).Month / 3m);
        }
    }
    

    You could use and array of Anonymous Types combined to LINQ to write a tests like this:

    [TestMethod]
    public void MonthReturnsProperQuarterWithOffset()
    {
        // Arrange
        var values = new[] {
            new { inputDate = new DateTime(2013, 1, 1), offset = 1, expectedQuarter = 2},
            new { inputDate = new DateTime(2013, 1, 1), offset = -1, expectedQuarter = 4},
            new { inputDate = new DateTime(2013, 4, 1), offset = 1, expectedQuarter = 3},
            new { inputDate = new DateTime(2013, 4, 1), offset = -1, expectedQuarter = 1},
            new { inputDate = new DateTime(2013, 7, 1), offset = 1, expectedQuarter = 4},
            new { inputDate = new DateTime(2013, 7, 1), offset = -1, expectedQuarter = 2},
            new { inputDate = new DateTime(2013, 10, 1), offset = 1, expectedQuarter = 1},
            new { inputDate = new DateTime(2013, 10, 1), offset = -1, expectedQuarter = 3}
            // Could add as many rows as you want, or extract to a private method that
            // builds the array of data
        }; 
        values.ToList().ForEach(val => 
        { 
            // Act 
            int actualQuarter = val.inputDate.GetQuarterNumber(val.offset); 
            // Assert 
            Assert.AreEqual(val.expectedQuarter, actualQuarter, 
                "Failed for inputDate={0}, offset={1} and expectedQuarter={2}.", val.inputDate, val.offset, val.expectedQuarter); 
            }); 
        }
    }
    

    When using this technique it's helpful to use a formatted message that includes the input data in the Assert to help you identify which row causes the test to fail.

    I've blogged about this solution with more background and detail at AgileCoder.net.

    0 讨论(0)
  • 2020-11-27 15:27

    Microsoft recently announced "MSTest V2" (see blog-article). This allows you to consistently (desktop, UWP, ...) use the DataRow-attribute!

     [TestClass]  
     public class StringFormatUtilsTest  
     {  
         [DataTestMethod]  
         [DataRow("tttt", "")]  
         [DataRow("", "")]  
         [DataRow("t3a4b5", "345")]  
         [DataRow("3&amp;amp;5*", "35")]  
         [DataRow("123", "123")]  
         public void StripNonNumeric(string before, string expected)  
         {  
             string actual = FormatUtils.StripNonNumeric(before);  
             Assert.AreEqual(expected, actual);  
         }  
     } 
    

    Again, Visual Studio Express' Test Explorer unfortunately doesn't recognize these tests. But at least the "full" VS versions now support that feature!

    To use it, just install the NuGet packages MSTest.TestFramework and MSTest.TestAdapter (both pre-release as of now).

    Older answer:

    If don't have to stick with MSTest and you're just using it for being able to run the tests via Test Explorer because you only have a Visual Studio Express edition, then this might be a solution for you:

    There's the VsTestAdapter VSIX extension for being able to run NUnit tests via Test Explorer. Unfortunately, VS Express users can't install extensions... But fortunately the VsTestAdapter comes with a plain NuGet-Package, too!

    So, if you're a VS Express user, just install the VsTestAdapter NuGet-Package and enjoy running your NUnit tests/testcases via Test Explorer!


    Unfortunately the aforementioned statement isn't true. While it's perfectly possible to install the package via an Express edition, it's useless, since it can't utilize the Test Explorer. There's previously been a side note on an older version of the TestAdapter, which was removed from the 2.0.0's description page:

    Note that it doesn't work with VS Express

    0 讨论(0)
  • 2020-11-27 15:33

    I know this is a late answer but hopefully it helps others out.

    I looked everywhere for an elegant solution and ended up writing one myself. We use it in over 20 projects with thousands of unit tests and hundreds of thousands of iterations. Never once missed a beat.

    https://github.com/Thwaitesy/MSTestHacks

    1) Install the NuGet package.

    2) Inherit your test class from TestBase

    public class UnitTest1 : TestBase
    { }
    

    3) Create a Property, Field or Method, that returns IEnumerable

    [TestClass]
    public class UnitTest1 : TestBase
    {
        private IEnumerable<int> Stuff
        {
            get
            {
                //This could do anything, get a dynamic list from anywhere....
                return new List<int> { 1, 2, 3 };
            }
        }
    }
    

    4) Add the MSTest DataSource attribute to your test method, pointing back to the IEnumerable name above. This needs to be fully qualified.

    [TestMethod]
    [DataSource("Namespace.UnitTest1.Stuff")]
    public void TestMethod1()
    {
        var number = this.TestContext.GetRuntimeDataSourceObject<int>();
    
        Assert.IsNotNull(number);
    }
    

    End Result: 3 iterations just like the normal DataSource :)

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using MSTestHacks;
    
    namespace Namespace
    {
        [TestClass]
        public class UnitTest1 : TestBase
        {
            private IEnumerable<int> Stuff
            {
                get
                {
                    //This could do anything, get a dynamic list from anywhere....
                    return new List<int> { 1, 2, 3 };
                }
            }
    
            [TestMethod]
            [DataSource("Namespace.UnitTest1.Stuff")]
            public void TestMethod1()
            {
                var number = this.TestContext.GetRuntimeDataSourceObject<int>();
    
                Assert.IsNotNull(number);
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 15:33

    Khlr gave a good detailed explanations and apparently this approach started working in VS2015 Express for Desktop. I tried to leave the comment, but my lack of reputation didn't allow me to do so.

    Let me copy the solution here:

    [TestClass]  
     public class StringFormatUtilsTest  
     {  
         [TestMethod]  
         [DataRow("tttt", "")]  
         [DataRow("", "")]  
         [DataRow("t3a4b5", "345")]  
         [DataRow("3&amp;amp;5*", "35")]  
         [DataRow("123", "123")]  
         public void StripNonNumeric(string before, string expected)  
         {  
             string actual = FormatUtils.StripNonNumeric(before);  
             Assert.AreEqual(expected, actual);  
         }  
     } 
    

    To use it, just install the NuGet packages MSTest.TestFramework and MSTest.TestAdapter.

    One problem is

    Error CS0433 The type 'TestClassAttribute' exists in both 'Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0 and 'Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0

    So, please remove Microsoft.VisualStudio.QualityTools.UnitTestFramework from references of the project.

    You're very welcome to edit the original reply and delete this one.

    0 讨论(0)
提交回复
热议问题