簡體   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