繁体   English   中英

MSTest 是否与 NUnit 的 TestCase 等效?

[英]Does MSTest have an equivalent to NUnit's TestCase?

我发现 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);  
     }  
 }  

Microsoft 最近发布了“MSTest V2” (请参阅博客文章)。 这使您可以始终如一地(桌面、UWP、...)使用DataRow

 [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 并且您只是为了能够通过测试资源管理器运行测试而使用它因为您只有 Visual Studio Express 版本 ,那么这可能是您的解决方案:

VsTestAdapter VSIX 扩展可以通过测试资源管理器运行 NUnit 测试。 不幸的是,VS Express 用户无法安装扩展……但幸运的是VsTestAdapter 也带有一个普通的 NuGet-Package

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


不幸的是,上述说法是不正确的。 虽然通过 Express 版本安装软件包是完全可能的,但它没有用,因为它不能使用测试资源管理器。 以前有一个关于旧版本的 TestAdapter 的旁注,它已从2.0.0 的描述页面中删除:

请注意,它不适用于 VS Express

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

我到处寻找一个优雅的解决方案,最后自己写了一个。 我们在 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);
        }
    }
}

我知道这是另一个迟到的答案,但在我的团队被锁定在使用 MS 测试框架中,我们开发了一种技术,该技术仅依赖于匿名类型来保存一组测试数据,并使用 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 上发表了有关此解决方案的更多背景和详细信息的博客

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 类型“TestClassAttribute”存在于“Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0 和”Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0

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

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

考虑使用DynamicDataAttribute

NUnit 测试用例

private static readonly IEnumerable<TestCaseData> _testCases = new[]
{
    new TestCaseData("input value 1").Returns(new NameValueCollection { { "a", "b" } }),
    new TestCaseData("input value 2").Returns(new NameValueCollection { { "a", "b" } }),
    /* .. */
};

[TestCaseSource(nameof(_testCases))]
public NameValueCollection test_test(string str)
{
    var collection = new NameValueCollection();
    collection.TestedMethod(str);
    return collection;
}

MSTest 测试用例

private static IEnumerable<object[]> _testCases
{
    get
    {
        return new[]
        {
            new object[] { "input value 1", new NameValueCollection { { "a", "b" } } },
            new object[] { "input value 2", new NameValueCollection { { "a", "b" } } },
            /* .. */
        };
    }
}

[TestMethod]
[DynamicData(nameof(_testCases))]
public void test_test(string str, NameValueCollection expectedResult)
{
    var collection = new NameValueCollection();
    collection.TestedMethod(str);

    CollectionAssert.AreEqual(expectedResult, collection);
}

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

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/有一个基于 XML 文件输入的教程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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