我知道 MSTest 不支持RowTest
和类似的测试。
MSTests
用户做什么?RowTest
没有支持怎么可能生活?
我已经看到DataDriven
了测试功能,但听起来开销太大,是否有任何 3rd 方补丁或工具可以让我在 中进行RowTest
类似的测试MSTest
?
我知道 MSTest 不支持RowTest
和类似的测试。
MSTests
用户做什么?RowTest
没有支持怎么可能生活?
我已经看到DataDriven
了测试功能,但听起来开销太大,是否有任何 3rd 方补丁或工具可以让我在 中进行RowTest
类似的测试MSTest
?
[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
}
我知道这是一个迟到的答案,但希望它可以帮助其他人。
我到处寻找一个优雅的解决方案,最后自己写了一个。我们在 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);
}
}
}
我们在 VS2012 Update1 中添加了对 DataRow 的支持。有关简要介绍,请参阅此博客
在 VS2012 Update1 中,此功能目前仅限于 Windows 商店应用程序。在以后的版本中,它不受此限制。
在我使用 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上发布了有关此解决方案的博客,其中包含更多背景和详细信息。
博客http://blog.drorhelper.com/2011/09/enabling-parameterized-tests-in-mstest.html中描述了使用 PostSharp 的类似于 DaTest(自 2008 年以来未更新)的解决方案
我已经通过使用不同数量的生成测试方法生成测试类代码解决了这个问题。您只需下载 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;
}
}
更多细节: