MSTest มีคุณสมบัติเทียบเท่ากับ TestCase ของ NUnit หรือไม่


107

ฉันพบว่าTestCaseคุณสมบัติใน NUnit มีประโยชน์มากเป็นวิธีที่รวดเร็วในการระบุพารามิเตอร์การทดสอบโดยไม่ต้องใช้วิธีแยกต่างหากสำหรับการทดสอบแต่ละครั้ง 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);  
     }  
 }  

คำถามที่คล้ายกันโปรดดูstackoverflow.com/questions/347535/how-to-rowtest-with-mstest/…
Michael Freidgeim

ทำไมคุณไม่ใช้ NUnit?
Mike de Klerk

1
@MikedeKlerk: Nunit ทำงานช้าอย่างไม่น่าเชื่อถ้าคุณใช้ Entity Framework ... เห็นได้ชัดว่าสะท้อนถึงคลาสที่คุณสร้างขึ้นทั้งหมดทุกครั้งที่คุณทำการทดสอบ
Robert Harvey

โดยทั่วไปแล้ว NUnit มีคุณสมบัติมากกว่า MSTest หากคุณใช้ MSTest เพียงเพื่อให้สามารถเรียกใช้การทดสอบของคุณด้วย VS Test Explorer คุณสามารถทำได้เช่นเดียวกันกับ NUnit โดยการติดตั้งส่วนขยาย NUnit Test Adapter ผ่าน NuGet
Stacked

คำตอบ:


62

Microsoft เพิ่งประกาศ"MSTest V2" (ดูบทความในบล็อก ) สิ่งนี้ช่วยให้คุณ (เดสก์ท็อป, 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 'Test Explorer ไม่รู้จักการทดสอบเหล่านี้ แต่อย่างน้อยตอนนี้ VS เวอร์ชัน "เต็ม" ก็รองรับฟีเจอร์นั้นแล้ว!

ในการใช้งานเพียงแค่ติดตั้งแพ็คเกจNuGet MSTest.TestFrameworkและMSTest.TestAdapter (ทั้งก่อนวางจำหน่าย ณ ตอนนี้)

คำตอบที่เก่ากว่า:

หากไม่จำเป็นต้องยึดติดกับ MSTest และคุณเพียงแค่ใช้มันเพื่อเรียกใช้การทดสอบผ่าน Test Explorer เนื่องจากคุณมีเฉพาะรุ่น Visual Studio Expressนี่อาจเป็นทางออกสำหรับคุณ:

มีส่วนขยาย VsTestAdapter VSIXเพื่อให้สามารถเรียกใช้การทดสอบ NUnit ผ่าน Test Explorer น่าเสียดายที่ผู้ใช้ VS Express ไม่สามารถติดตั้งส่วนขยายได้ ... แต่โชคดีที่VsTestAdapter มาพร้อมกับ NuGet-Package ธรรมดาด้วย!

ดังนั้นหากคุณเป็นผู้ใช้ VS Express เพียงแค่ติดตั้ง VsTestAdapter NuGet-Package และสนุกกับการเรียกใช้การทดสอบ NUnit ของคุณผ่าน Test Explorer!


น่าเสียดายที่คำสั่งดังกล่าวไม่เป็นความจริง แม้ว่าจะสามารถติดตั้งแพ็คเกจผ่าน Express edition ได้อย่างสมบูรณ์แบบ แต่ก็ไม่มีประโยชน์เนื่องจากไม่สามารถใช้ Test Explorer ได้ ก่อนหน้านี้มีบันทึกด้านข้างเกี่ยวกับ TestAdapter เวอร์ชันเก่ากว่าซึ่งถูกลบออกจากหน้าคำอธิบายของ 2.0.0 :

โปรดทราบว่ามันใช้ไม่ได้กับ VS Express


4
MSTest "v2" เป็นเฟรมเวิร์กเริ่มต้นเมื่อใช้ VS 2017 ตอนนี้ซึ่งจะได้รับการสนับสนุน 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 ในวิธีการทดสอบของคุณโดยชี้กลับไปที่ชื่อที่สามารถคำนวณได้ของ IE ด้านบน สิ่งนี้จำเป็นต้องมีคุณสมบัติครบถ้วน

[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

เนื่องจากมีการเปลี่ยนแปลงในห้องสมุดต้นแบบนี้ไม่ได้ทำงานกับMSTEST "v2" นี่คือค่าเริ่มต้นสำหรับ VS15 (VS 2017)
Marc L.

3
ใช่ถ้าคุณใช้ MSTest V2 มีผู้ให้บริการกรณีทดสอบใหม่ที่คล้ายกับ NUnit ดังนั้นจึงไม่จำเป็นต้องทำงานนี้👏
Thwaitesy

ดูเหมือนจะใช้ไม่ได้ใน VS 2015 ไฟล์กำหนดค่าของแอปไม่ได้รับการเติมข้อมูลแบบไดนามิกจึงไม่พบแหล่งข้อมูล
Reed

13

ฉันรู้ว่านี่เป็นอีกหนึ่งคำตอบที่ล่าช้า แต่ในทีมของฉันที่ถูกล็อกไว้ในการใช้กรอบการทดสอบ MS เราได้พัฒนาเทคนิคที่อาศัยเฉพาะ Anonymous types เพื่อเก็บข้อมูลการทดสอบอาร์เรย์และ 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);
    }
}

คุณสามารถใช้และอาร์เรย์ของ Anonymous types รวมกับ 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 เพื่อช่วยคุณระบุว่าแถวใดที่ทำให้การทดสอบล้มเหลว

ฉันได้ blogged เกี่ยวกับการแก้ปัญหานี้ที่มีพื้นหลังมากขึ้นและรายละเอียดที่AgileCoder.net


4
ปัญหาใหญ่ที่สุดคือถ้ากรณีใด ๆ ล้มเหลวจากอาร์เรย์ของค่าการทดสอบทั้งหมดล้มเหลวและไม่มีการทดสอบกรณีใด ๆ อีก
ytoledano

สิ่งนี้จะสร้างกรณีทดสอบที่อาจมีอิทธิพลต่อกันและกัน
BartoszKP

@BartoszKP เฉพาะในกรณีที่ระบบที่อยู่ระหว่างการทดสอบมีผลข้างเคียงซึ่งในกรณีนี้อาจไม่ใช่เทคนิคที่ดีที่สุด
Gary.Ray

@ Gary.Ray นอกจากนี้เมื่อระบบไม่ได้มีผลข้างเคียงเลย นอกจากนี้เมื่อการทดสอบไม่ผ่านและนักพัฒนารายอื่นพยายามแก้ไขและเสียเวลาหลายชั่วโมงในการพยายามคิดว่าการพึ่งพานั้นสำคัญหรือไม่ นี่เป็นเพียงสิ่งที่คุณไม่ควรทำในช่วงเวลาหนึ่ง
BartoszKP

ดีพอแล้ว. +1
Trey Mack

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.TestFrameworkและMSTest.TestAdapter

ปัญหาหนึ่งคือ

ข้อผิดพลาด CS0433 ชนิด 'TestClassAttribute' มีอยู่ทั้งใน 'Microsoft.VisualStudio.QualityTools.UnitTestFramework เวอร์ชัน = 10.0.0.0 และ' Microsoft.VisualStudio.TestPlatform.TestFramework เวอร์ชัน = 14.0.0.0

ดังนั้นโปรดลบMicrosoft.VisualStudio.QualityTools.UnitTestFrameworkออกจากการอ้างอิงของโครงการ

คุณยินดีอย่างยิ่งที่จะแก้ไขคำตอบเดิมและลบคำตอบนี้


0

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.