MSTest是否与NUnit的TestCase相当?

时间:2021-10-18 12:00:11

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 similar in MSTest?

我发现NUnit中的TestCase功能非常有用,可以快速指定测试参数,而无需为每个测试使用单独的方法。 MSTest中有类似的东西吗?

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

5 个解决方案

#1


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:

如果不必坚持使用MSTest并且您只是使用它来通过Test Explorer运行测试,因为您只有Visual Studio Express版本,那么这可能是您的解决方案:

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!

VsTestAdapter VSIX扩展可以通过Test Explorer运行NUnit测试。不幸的是,VS Express用户无法安装扩展......但幸运的是,VsTestAdapter也带有一个简单的NuGet-Package!

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

因此,如果您是VS Express用户,只需安装VsTestAdapter NuGet-Package并享受通过Test Explorer运行NUnit测试/测试用例的乐趣!


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:

不幸的是,上述陈述并非如此。虽然完全可以通过Express版本安装软件包,但它没用,因为它无法使用Test Explorer。以前有关于旧版TestAdapter的附注,该版本已从2.0.0的描述页面中删除:

Note that it doesn't work with VS Express

请注意,它不适用于VS Express


Update:

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

微软最近宣布推出“MSTest V2”(参见博客文章)。这使您可以始终如一地(桌面,UWP,...)使用DataRow属性!

 [TestClass]  
 public class StringFormatUtilsTest  
 {  
     [TestMethod]  
     [DataRow("tttt", "")]  
     [DataRow("", "")]  
     [DataRow("t3a4b5", "345")]  
     [DataRow("3&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!

同样,Visual Studio Express的测试资源管理器遗憾地无法识别这些测试。但至少“完整”VS版本现在支持该功能!

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

要使用它,只需安装NuGet包MSTest.TestFramework和MSTest.TestAdapter(两者都是预发布版)。

#2


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.

我到处寻找一个优雅的解决方案,最后自己写了一个。我们在20多个项目中使用它,进行了数千次单元测试和数十万次迭代。永远不会错过一个节拍。

https://github.com/Thwaitesy/MSTestHacks

1) Install the NuGet package.

1)安装NuGet包。

2) Inherit your test class from TestBase

2)从TestBase继承您的测试类

public class UnitTest1 : TestBase
{ }

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

3)创建一个返回IEnumerable的Property,Field或Method

[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.

4)将MSTest DataSource属性添加到测试方法,指向上面的IEnumerable名称。这需要完全合格。

[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 :)

最终结果:3次迭代就像普通的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);
        }
    }
}

#3


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.

我知道这是另一个迟到的答案,但在我的团队被锁定使用MS Test框架时,我们开发了一种技术,它只依赖于匿名类型来保存测试数据数组,并且LINQ循环并测试每一行。它不需要额外的类或框架,并且往往相当容易阅读和理解。它比使用外部文件或连接数据库的数据驱动测试更容易实现。

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:

您可以使用和匿名类型的数组组合到LINQ来编写这样的测试:

[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.

使用此技术时,使用包含Assert中输入数据的格式化消息有助于您确定哪一行导致测试失败。

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

我在AgileCoder.net上发布了有关此解决方案的更多背景和详细信息。

#4


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.

Khlr给出了很好的详细解释,显然这种方法开始在VS2015 Express for Desktop中运行。我试图留下评论,但我缺乏声誉不允许我这样做。

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.

要使用它,只需安装NuGet包MSTest.TestFramework和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

错误CS0433类型'TestClassAttribute'存在于'Microsoft.VisualStudio.QualityTools.UnitTestFramework,Version = 10.0.0.0和'Microsoft.VisualStudio.TestPlatform.TestFramework,Version = 14.0.0.0

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

因此,请从项目的引用中删除Microsoft.VisualStudio.QualityTools.UnitTestFramework。

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

非常欢迎您编辑原始回复并删除此回复。

#5


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.

MSTest具有DataSource属性,允许您为其提供数据库表,csv,xml等。我已经使用它并且它运行良好。我不知道如何将数据放在上面作为问题的属性,但是设置外部数据源非常容易,文件可以包含在项目中。我从一开始就运行了一个小时,而且我不是一名自动化测试专家。

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

https://msdn.microsoft.com/en-us/library/ms182527.aspx?f=255&MSPPError=-2147217396有一个基于数据库输入的完整教程。

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

http://www.rhyous.com/2015/05/11/row-tests-or-paramerterized-tests-mstest-xml/有一个基于XML文件输入的教程。

#1


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:

如果不必坚持使用MSTest并且您只是使用它来通过Test Explorer运行测试,因为您只有Visual Studio Express版本,那么这可能是您的解决方案:

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!

VsTestAdapter VSIX扩展可以通过Test Explorer运行NUnit测试。不幸的是,VS Express用户无法安装扩展......但幸运的是,VsTestAdapter也带有一个简单的NuGet-Package!

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

因此,如果您是VS Express用户,只需安装VsTestAdapter NuGet-Package并享受通过Test Explorer运行NUnit测试/测试用例的乐趣!


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:

不幸的是,上述陈述并非如此。虽然完全可以通过Express版本安装软件包,但它没用,因为它无法使用Test Explorer。以前有关于旧版TestAdapter的附注,该版本已从2.0.0的描述页面中删除:

Note that it doesn't work with VS Express

请注意,它不适用于VS Express


Update:

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

微软最近宣布推出“MSTest V2”(参见博客文章)。这使您可以始终如一地(桌面,UWP,...)使用DataRow属性!

 [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);  
     }  
 } 

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

同样,Visual Studio Express的测试资源管理器遗憾地无法识别这些测试。但至少“完整”VS版本现在支持该功能!

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

要使用它,只需安装NuGet包MSTest.TestFramework和MSTest.TestAdapter(两者都是预发布版)。

#2


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.

我到处寻找一个优雅的解决方案,最后自己写了一个。我们在20多个项目中使用它,进行了数千次单元测试和数十万次迭代。永远不会错过一个节拍。

https://github.com/Thwaitesy/MSTestHacks

1) Install the NuGet package.

1)安装NuGet包。

2) Inherit your test class from TestBase

2)从TestBase继承您的测试类

public class UnitTest1 : TestBase
{ }

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

3)创建一个返回IEnumerable的Property,Field或Method

[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.

4)将MSTest DataSource属性添加到测试方法,指向上面的IEnumerable名称。这需要完全合格。

[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 :)

最终结果:3次迭代就像普通的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);
        }
    }
}

#3


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.

我知道这是另一个迟到的答案,但在我的团队被锁定使用MS Test框架时,我们开发了一种技术,它只依赖于匿名类型来保存测试数据数组,并且LINQ循环并测试每一行。它不需要额外的类或框架,并且往往相当容易阅读和理解。它比使用外部文件或连接数据库的数据驱动测试更容易实现。

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:

您可以使用和匿名类型的数组组合到LINQ来编写这样的测试:

[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.

使用此技术时,使用包含Assert中输入数据的格式化消息有助于您确定哪一行导致测试失败。

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

我在AgileCoder.net上发布了有关此解决方案的更多背景和详细信息。

#4


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.

Khlr给出了很好的详细解释,显然这种方法开始在VS2015 Express for Desktop中运行。我试图留下评论,但我缺乏声誉不允许我这样做。

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.

要使用它,只需安装NuGet包MSTest.TestFramework和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

错误CS0433类型'TestClassAttribute'存在于'Microsoft.VisualStudio.QualityTools.UnitTestFramework,Version = 10.0.0.0和'Microsoft.VisualStudio.TestPlatform.TestFramework,Version = 14.0.0.0

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

因此,请从项目的引用中删除Microsoft.VisualStudio.QualityTools.UnitTestFramework。

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

非常欢迎您编辑原始回复并删除此回复。

#5


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.

MSTest具有DataSource属性,允许您为其提供数据库表,csv,xml等。我已经使用它并且它运行良好。我不知道如何将数据放在上面作为问题的属性,但是设置外部数据源非常容易,文件可以包含在项目中。我从一开始就运行了一个小时,而且我不是一名自动化测试专家。

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

https://msdn.microsoft.com/en-us/library/ms182527.aspx?f=255&MSPPError=-2147217396有一个基于数据库输入的完整教程。

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

http://www.rhyous.com/2015/05/11/row-tests-or-paramerterized-tests-mstest-xml/有一个基于XML文件输入的教程。