如何在MSTest中运行具有多个参数的测试方法?

时间:2012-01-26 16:50:11

标签: c# unit-testing nunit mstest vs-unit-testing-framework

NUnit有一个名为Values的功能,如下所示:

[Test]
public void MyTest(
    [Values(1,2,3)] int x,
    [Values("A","B")] string s)
{
    // ...
}

这意味着测试方法将运行6次:

MyTest(1, "A")
MyTest(1, "B")
MyTest(2, "A")
MyTest(2, "B")
MyTest(3, "A")
MyTest(3, "B")

我们现在正在使用MSTest,是否有任何相同的功能,以便我可以使用多个参数运行相同的测试?

[TestMethod]
public void Mytest()
{
    // ...
}

9 个答案:

答案 0 :(得分:130)

编辑4 :看起来这已在2016年6月17日的MSTest V2中完成:https://blogs.msdn.microsoft.com/visualstudioalm/2016/06/17/taking-the-mstest-framework-forward-with-mstest-v2/

原始答案

截至大约一周前,在Visual Studio 2012 Update 1中,现在可以实现类似的功能:

[DataTestMethod]
[DataRow(12,3,4)]
[DataRow(12,2,6)]
[DataRow(12,4,3)]
public void DivideTest(int n, int d, int q)
{
  Assert.AreEqual( q, n / d );
}

编辑:它似乎仅在 WinRT / Metro 的单元测试项目中可用。长号

编辑2 :以下是使用Visual Studio中的“转到定义”找到的元数据:

#region Assembly Microsoft.VisualStudio.TestPlatform.UnitTestFramework.dll, v11.0.0.0
// C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0\ExtensionSDKs\MSTestFramework\11.0\References\CommonConfiguration\neutral\Microsoft.VisualStudio.TestPlatform.UnitTestFramework.dll
#endregion

using System;

namespace Microsoft.VisualStudio.TestPlatform.UnitTestFramework
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public class DataTestMethodAttribute : TestMethodAttribute
    {
        public DataTestMethodAttribute();

        public override TestResult[] Execute(ITestMethod testMethod);
    }
}

编辑3 :此问题在Visual Studio的UserVoice论坛中提出。 最后更新声明:

  

开始·Visual Studio Team ADMIN Visual Studio Team(产品   团队,Microsoft Visual Studio)回复·2016年4月25日谢谢   反馈。我们已经开始研究这个问题了。

     

Pratap Lakshman Visual Studio

https://visualstudio.uservoice.com/forums/330519-team-services/suggestions/3865310-allow-use-of-datatestmethod-datarow-in-all-unit

答案 1 :(得分:43)

很遗憾,MSTest不支持。显然有一个extensibility model and you can implement it yourself。另一种选择是使用data-driven tests

我个人的意见是坚持使用NUnit ......

编辑:从Visual Studio 2012,更新1开始,MSTest具有类似的功能。请参阅下面的@ McAden's answer

答案 2 :(得分:23)

此功能现在位于pre-release,适用于VS 2015.

例如:

[TestClass]
public class UnitTest1
{
    [DataTestMethod]
    [DataRow(1, 2, 2)]
    [DataRow(2, 3, 5)]
    [DataRow(3, 5, 8)]
    public void AdditionTest(int a, int b, int result)
    {
        Assert.AreEqual(result, a + b);
    }
}

答案 3 :(得分:10)

由于没有人提及 - 与NUnit的Value(或TestCase)属性不完全相同,但MSTest具有DataSource属性,这允许您执行类似的操作。您可以将其连接到数据库或XML文件 - 不像NUnit的功能那么简单,但可以完成工作。

答案 4 :(得分:7)

MSTest有一个名为DataSource的强大属性,使用此属性可以按照要求执行数据驱动测试。您可以将测试数据包含在XML,CSV或数据库中。以下是一些指导您的链接

http://visualstudiomagazine.com/articles/2009/09/15/unit-testing-with-vsts2008-part-3.aspx http://msdn.microsoft.com/en-us/library/ms182527.aspx
http://msdn.microsoft.com/en-us/library/ms243192.aspx

希望这会对你有所帮助。

答案 5 :(得分:4)

MsTest不支持该功能,但您可以实现自己的属性来实现该功能。 看看下面的内容:

http://blog.drorhelper.com/2011/09/enabling-parameterized-tests-in-mstest.html

答案 6 :(得分:4)

当然,有另一种方法可以做到这一点,这个方法没有在这个线程中讨论过,即通过继承包含TestMethod的类。在以下示例中,仅定义了一个TestMethod,但已经完成了两个测试用例。

在Visual Studio 2012中,它在TestExplorer中创建了两个测试:

  1. DemoTest_B10_A5.test
  2. DemoTest_A12_B4.test

    public class Demo
    {
        int a, b;
    
        public Demo(int _a, int _b)
        {
            this.a = _a;
            this.b = _b;
        }
    
        public int Sum()
        {
            return this.a + this.b;
        }
    }
    
    public abstract class DemoTestBase
    {
        Demo objUnderTest;
        int expectedSum;
    
        public DemoTestBase(int _a, int _b, int _expectedSum)
        {
            objUnderTest = new Demo(_a, _b);
            this.expectedSum = _expectedSum;
        }
    
        [TestMethod]
        public void test()
        {
            Assert.AreEqual(this.expectedSum, this.objUnderTest.Sum());
        }
    }
    
    [TestClass]
    public class DemoTest_A12_B4 : DemoTestBase
    {
        public DemoTest_A12_B4() : base(12, 4, 16) { }
    }
    
    public abstract class DemoTest_B10_Base : DemoTestBase
    {
        public DemoTest_B10_Base(int _a) : base(_a, 10, _a + 10) { }
    }
    
    [TestClass]
    public class DemoTest_B10_A5 : DemoTest_B10_Base
    {
        public DemoTest_B10_A5() : base(5) { }
    }
    

答案 7 :(得分:4)

实现起来非常简单 - 您应该使用TestContext属性和TestPropertyAttribute

实施例

public TestContext TestContext { get; set; }
private List<string> GetProperties()
{
    return TestContext.Properties
        .Cast<KeyValuePair<string, object>>()
        .Where(_ => _.Key.StartsWith("par"))
        .Select(_ => _.Value as string)
        .ToList();
}

//usage
[TestMethod]
[TestProperty("par1", "http://getbootstrap.com/components/")]
[TestProperty("par2", "http://www.wsj.com/europe")]
public void SomeTest()
{
    var pars = GetProperties();
    //...
}

答案 8 :(得分:3)

我无法让DataRowAttribute在Visual Studio 2015中工作,这就是我最终的目标:

[TestClass]
public class Tests
{
    private Foo _toTest;

    [TestInitialize]
    public void Setup()
    {
        this._toTest = new Foo();       
    }

    [TestMethod]
    public void ATest()
    {
        this.Perform_ATest(1, 1, 2);
        this.Setup();

        this.Perform_ATest(100, 200, 300);
        this.Setup();

        this.Perform_ATest(817001, 212, 817213);
        this.Setup();

    }

    private void Perform_ATest(int a, int b, int expected)
    {
        //Obviously this would be way more complex...

        Assert.IsTrue(this._toTest.Add(a,b) == expected);    
    }
}

public class Foo
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}

这里的真正解决方案是使用NUnit(除非你像我在这个特定的实例中一样陷入MSTest)。