如何在 Visual Studio 2010 中并行化数据驱动的单元测试?

Posted

技术标签:

【中文标题】如何在 Visual Studio 2010 中并行化数据驱动的单元测试?【英文标题】:How to parallelize a Data-Driven unit test in Visual Studio 2010? 【发布时间】:2011-05-02 01:47:34 【问题描述】:

我知道通过在测试解决方案的.testresults 文件中指定parallelTestCount 属性,可以在多核机器上并行化常规的MS-Test 单元测试(当然需要注意事项)。像这样,

<Execution parallelTestCount="1">
    <TestTypeSpecific />
    <AgentRule name="Execution Agents"></AgentRule>
</Execution>

MSDN 上的更多信息:Executing Unit Tests in parallel on a multi-CPU/core machine

但是,我有一个数据驱动的测试,类似这样,这只是一个测试,但输入来自 csv 并运行 1000 条记录通过同样的测试。

[DeploymentItem("InputDataRows.csv"), Timeout(37800000), DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\\InputDataRow.csv", "InputDataRow#csv", DataAccessMethod.Sequential)]                
[TestMethod]
public void RunProcessing()

    int userId = Convert.ToInt32(TestContext.DataRow[0].ToString());
    int connId = Convert.ToInt32(TestContext.DataRow[1].ToString());
    string xml = TestHelper.GetDataFromDb(userId, connId);
    a = doStuffA(xml); 
    b = doStuffB(xml);
    Assert.IsTrue(a == b);

因为这是一个缓慢的过程,我正在考虑并行化这个单元测试。

属性上的Sequential enum只是它访问数据的方式,另一个选项是Random,仍然是串行而不是并行。

【问题讨论】:

您使用什么语言? C#? 您使用的是什么版本的 .Net?另外,您能否提供一些有关如何设置 TestContext 的详细信息? 【参考方案1】:

为了并行化此单元测试,您需要 doStuffA()doStuffB() 才能对数据的子集(例如,一次处理一个块或什至 csv 的一行)进行操作。如果您可以重构您的方法以这种方式运行,您可以利用任务或并行 foreach 循环,以便此测试并行执行。假设您的方法被重构以处理您的 csv 行,您可以执行以下操作:

int userId = Convert.ToInt32(TestContext.DataRow[0].ToString());
int connId = Convert.ToInt32(TestContext.DataRow[1].ToString());
string xml = TestHelper.GetDataFromDb(userId, connId);
var rows = xml.Split('\n');

Parallel.ForEach(rows, (row) =>

    var a = doStuffOnRowA(row);
    var b = doStuffOnRowB(row);
    Assert.AreEqual(a, b);
);

【讨论】:

【参考方案2】:

这可能看起来有点复杂,但请听我说完。 MSTest 有一个限制,即您实际上不能并行运行数据驱动的测试。 我过去为解决这个问题所做的是在 Visual Studio 中创建一个“自定义工具”。

https://msdn.microsoft.com/en-us/library/bb166508.aspx

https://msdn.microsoft.com/en-us/library/bb166817.aspx

我们创建的自定义工具执行以下操作:

    将 csv 拆分为多个 csv 文件,每个文件只有一行。 为每个新生成的 csv 生成单独的测试。

生成这些测试时,我们将特定的测试属性放在它们上面,因此我们可以指定只运行具有该属性的测试。

这听起来有点过头了,但如果您在构建自定义工具方面做得很好,这实际上是一个非常顺利的过程。

【讨论】:

【参考方案3】:

如果 xml 中没有数据被更改(或者方法没有修改 xml 的相同部分),那么你可以这样做..

var numCompleted = 0;
var a = Task.Run(() =>  doStuffOnRowA(xml); );
var b = Task.Run(() =>  doStuffOnRowB(xml); );
Task.WaitAll(new Task[2]  a, b );

如果您复制和粘贴这种伪代码,这可能不会运行。 不完全是 Parallel,但至少会同时运行!

【讨论】:

在等待多任务时最好使用框架的这个功能 Task.WaitAll msdn.microsoft.com/en-us/library/windows/apps/… 谢谢,我刚改了!【参考方案4】:

不支持并行执行数据驱动测试。请看这里:RFC 004 - In-assembly Parallel Execution

【讨论】:

对于寻找这个的人,请参阅文档中的最后一行:“4. 数据驱动测试的执行将不会被并行化 - 即不支持对 DataRow 属性进行并行化。”【参考方案5】:

据我所知:测试中的各个数据行不是并行运行的。但如果您有多个单元测试,它们确实会并行运行。

【讨论】:

以上是关于如何在 Visual Studio 2010 中并行化数据驱动的单元测试?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Visual Studio 2010 中使用 Visual Studio 2008 创建的 DLL?

visual studio 2010不能正确安装,急求

关于在Visual Studio2010中如何卸载Visual Asixist这个插件?为啥将它卸载后Visual Studio启动后仍然有

电脑里的visual studio 2010怎么打开

如何在 Visual Studio 2010 中使用互斥锁

如何在 Visual Studio 2010 中设置默认编码