【问题标题】:How to RowTest with MSTest?如何使用 MSTest 进行行测试?
【发布时间】:2010-09-25 17:47:16
【问题描述】:

我知道 MSTest 不支持 RowTest 和类似的测试。

MSTests 用户是做什么的?没有RowTest 的支持,怎么可能活下去?

我见过DataDriven 测试功能,但听起来开销太大,是否有任何第三方补丁或工具可以让我在RowTest 中进行RowTest 类似的测试@?

【问题讨论】:

标签: unit-testing mstest data-driven-tests rowtest


【解决方案1】:
[TestMethod]
Test1Row1
{
    Test1(1,4,5);
}

[TestMethod]
Test1Row2
{
    Test1(1,7,8);
}

private Test1(int i, int j, int k)
{
   //all code and assertions in here
}

【讨论】:

  • 这是我使用过的方法,它还可以让你给每个“行”一个单独的,希望是描述性的名称。
【解决方案2】:

博客http://blog.drorhelper.com/2011/09/enabling-parameterized-tests-in-mstest.html中描述了使用 PostSharp 的类似于 DaTest(自 2008 年以来未更新)的解决方案

【讨论】:

    【解决方案3】:

    我们在 VS2012 Update1 中添加了对 DataRow 的支持。 See this blog for a breif introduction

    在 VS2012 Update1 中,此功能目前仅限于 Windows 商店应用。以后的版本就没有这个限制了。

    【讨论】:

    • 为什么它仅限于 Windows 商店应用程序?它会很快用于常规测试项目吗?
    • xUnit 已经有这么久了。这是一种常见的情况,为什么只对 Windows 应用商店应用启用此功能?这没有任何意义。
    • @DevDave 虽然我不知道 vnext 计划,但有一个适配器可用于提供类似功能的旧版 mstest 项目。有关详细信息,请参阅此博客:blogs.msdn.com/b/vstsqualitytools/archive/2009/09/04/…
    • @allen 明白了。在创建 MSTest 的公司内部工作比在外部工作更令人大开眼界。有趣的是,我建议在 MSTest 上使用 xUnit.net。
    • 它现在可用于所有平台,而不仅仅是 Windows 应用商店应用程序。
    【解决方案4】:

    我通过使用不同数量的生成测试方法生成测试类代码解决了这个问题。您只需下载 2 个文件并将它们包含到您的项目中。
    然后在测试代码中子类化一个具有所需行数的类并实现 2 个抽象方法:

    [TestClass]
    public class Ha_ha_ha_Test: MsTestRows.Rows.TestRows_42<string>
    {
        public override void TestMethod(string dataRow, int rowNumber)
        {
            Console.WriteLine(dataRow);
            Assert.IsFalse(dataRow.Contains("3"));
        }
    
        public override string GetNextDataRow(int rowNumber)
        {
            return "data" + rowNumber;
        }
    }
    

    更多详情:

    https://github.com/dzhariy/mstest-rows

    【讨论】:

      【解决方案5】:

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

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

      https://github.com/Thwaitesy/MSTestHacks

      1) 安装NuGet 包。

      2)从TestBase继承你的测试类

      public class UnitTest1 : TestBase
      { }
      

      3) 创建一个返回 IEnumerable 的属性、字段或方法

      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 名称。这需要完全限定。

      [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
      {
          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 };
                  }
              }
      
              [DataSource("Namespace.UnitTest1.Stuff")]
              public void TestMethod1()
              {
                  var number = this.TestContext.GetRuntimeDataSourceObject<int>();
      
                  Assert.IsNotNull(number);
              }
          }
      }
      

      【讨论】:

      • 非常感谢,@Thwaitesy!你为我节省了很多时间。
      【解决方案6】:

      在我的团队使用 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 上发布了有关此解决方案的更多背景和详细信息的博客。

      【讨论】:

        猜你喜欢
        • 2012-01-13
        • 2011-09-24
        • 1970-01-01
        • 2011-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多