MSTest是否与NUnit的TestCase等效?


107

我发现TestCaseNUnit中的功能非常有用,可以快速指定测试参数,而无需为每个测试使用单独的方法。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);  
     }  
 }  


为什么不使用NUnit?
Mike de Klerk

1
@MikedeKlerk:如果您使用的是Entity Framework,Nunit的运行速度会令人难以置信...显然,每次运行测试时,它都会反映所有生成的类。
罗伯特·哈维

一般来说,NUnit比MSTest具有更多的功能,如果您使用MSTest只是为了能够通过VS Test Explorer运行测试,则可以通过NuGet安装NUnit Test Adapter扩展来对NUnit进行同样的操作
堆叠

Answers:


62

微软最近宣布了“ MSTest V2”(请参阅blog-article)。这使您能够(桌面,UWP等)一致地使用DataRow-attribute!

 [TestClass]  
 public class StringFormatUtilsTest  
 {  
     [DataTestMethod]  
     [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);  
     }  
 } 

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

要使用它,只需安装NuGet软件包MSTest.TestFrameworkMSTest.TestAdapter(截至目前都是预发行版本)。

较旧的答案:

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

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

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


不幸的是,上述陈述是不正确的。尽管完全可以通过Express版本安装该软件包,但它无用,因为它无法利用Test Explorer。以前有一个关于旧版本的TestAdapter的注释,该注释已从2.0.0的描述页面中删除:

请注意,它不适用于VS Express


4
现在,使用VS 2017时,MSTest“ v2”是默认框架。由于最新版本的OOTB将支持此功能,因此该信息可能应该放在答案的顶部。
Marc L.

34

我知道这是一个较晚的答案,但希望它可以帮助其他人。

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

https://github.com/Thwaitesy/MSTestHacks

1)安装NuGet软件包。

2)从TestBase继承您的测试类

public class UnitTest1 : TestBase
{ }

3)创建返回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)将MSTest DataSource属性添加到您的测试方法中,指向上面的IEnumerable名称。这需要完全合格。

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

    Assert.IsNotNull(number);
}

最终结果: 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);
        }
    }
}

每种情况下都可以使用多个参数吗?
Lonefish '16

因为基础库中有更改,所以这不适用于MsTest“ v2”。这是VS15(VS 2017)的默认设置。
Marc L.

3
是的,如果您使用的是MSTest V2,则有一个类似于NUnit的新测试用例提供程序。因此,👏周围不需要进行此项工作
Thwaitesy

这似乎在VS 2015中不起作用,应用程序配置文件没有动态填充,因此找不到数据源
Reed

13

我知道这是另一个较晚的答案,但是在我的团队无法使用MS Test框架的情况下,我们开发了一种技术,该技术仅依赖于匿名类型来保存测试数据数组,而LINQ可以遍历并测试每一行。它不需要其他类或框架,并且往往相当容易阅读和理解。与使用外部文件或连接的数据库进行数据驱动的测试相比,实现起来也容易得多。

例如,假设您有如下扩展方法:

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

您可以使用结合到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); 
        }); 
    }
}

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

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


4
与此相关的最大问题是,如果任何一种情况都无法在值数组中进行,则整个测试都会失败,并且不再测试更多的情况。
ytoledano '16

这将创建可能相互影响的测试用例。
BartoszKP

@BartoszKP仅当被测系统有副作用时,在这种情况下这可能不是最佳技术。
Gary.Ray

@ Gary.Ray此外,当系统没有副作用还没有。同样,当测试未通过且另一位开发人员试图修复该问题时,则浪费了数小时来尝试确定依赖性是否重要。这段时间,这只是您不应该做的事情。
BartoszKP

够好了。+1
Trey Mack '18年

7

Khlr给出了很好的详细解释,显然,这种方法已在VS2015 Express for Desktop中开始使用。我试图发表评论,但由于缺乏声誉,我无法这样做。

让我在这里复制解决方案:

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

要使用它,只需安装NuGet软件包MSTest.TestFrameworkMSTest.TestAdapter

一个问题是

错误CS0433,Microsoft.VisualStudio.QualityTools.UnitTestFramework,版本= 10.0.0.0和Microsoft.VisualStudio.TestPlatform.TestFramework,版本= 14.0.0.0中都存在类型“ TestClassAttribute”

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

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


0

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

https://msdn.microsoft.com/zh-cn/library/ms182527.aspx?f=255&MSPPError=-2147217396包含基于数据库输入的完整教程。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.