C# 如何并行运行单元测试(MSTest)?
我正在寻找并行运行测试套件的方法 我知道C# 如何并行运行单元测试(MSTest)?,c#,visual-studio,web-services,unit-testing,parallel-processing,C#,Visual Studio,Web Services,Unit Testing,Parallel Processing,我正在寻找并行运行测试套件的方法 我知道.testrunconfig设置。这允许您对CPU数量进行多路复用 我想并行运行1000个测试。这是有意义的,因为我正在测试一个web服务,所以测试中90%的时间都在等待服务响应 有没有办法解决这个问题?这些测试是为VS编写的,但我愿意在VS之外运行它们 稍后编辑:Visual Studio测试团队已在VS 2015更新1中添加了此项。见下面马克·索乌尔的回答 使用该方法最多可以得到5个 请记住,使用它可能会出现并发性问题,因为MSTest并没有完全隔离每
.testrunconfig
设置。这允许您对CPU数量进行多路复用
我想并行运行1000个测试。这是有意义的,因为我正在测试一个web服务,所以测试中90%的时间都在等待服务响应
有没有办法解决这个问题?这些测试是为VS编写的,但我愿意在VS之外运行它们
稍后编辑:Visual Studio测试团队已在VS 2015更新1中添加了此项。见下面马克·索乌尔的回答 使用该方法最多可以得到5个 请记住,使用它可能会出现并发性问题,因为MSTest并没有完全隔离每个测试(例如,静态会使原本要运行一次的代码变得有趣)
(不知道为什么限制为5,但如果
parallelTestCount
设置为5以上,MSTest将不会并行运行它们。根据下面的注释,此规则显然随Visual Studio 2013而改变)我发现C:\Program Files(x86)\Microsoft Visual Studio 11.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe
将使用.testsettings
文件运行并行测试,该文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<TestSettings name="TestSettings1" id="21859d0f-7bdc-4165-b9ad-05fc803c9ee9" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Description>These are default test settings for a local test run.</Description>
<Deployment enabled="false" />
<Execution parallelTestCount="8">
<TestTypeSpecific>
<UnitTestRunConfig testTypeId="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b">
<AssemblyResolution>
<TestDirectory useLoadContext="true" />
</AssemblyResolution>
</UnitTestRunConfig>
</TestTypeSpecific>
<AgentRule name="Execution Agents">
</AgentRule>
</Execution>
</TestSettings>
这些是本地测试运行的默认测试设置。
Visual Studio 2015更新1添加了这一点。
对于更新2,在测试资源管理器窗格顶部的工具栏中(在“分组”和“搜索”框之间)有一个UI切换按钮
对于更新1,在.runsettings中设置以下内容
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<RunConfiguration>
<MaxCpuCount>0</MaxCpuCount>
</RunConfiguration>
</RunSettings>
0
MaxCpuCount的值具有以下语义:
•'n'(其中1以上的答案肯定有助于我澄清问题,但是,约翰·科纳博客中的这一点:是我们遗漏的一点
并行测试执行利用计算机上的可用内核,通过在每个可用内核上启动测试执行引擎作为一个不同的进程,并将一个容器(程序集、DLL或包含要执行的测试的相关工件)交给它来实现,该容器相当于要执行的测试
-->“单独的容器位是我缺少的部分。为了让我的测试并行运行,我需要将我的测试拆分为单独的测试程序集。完成后,我看到不同程序集中的测试并行运行。”
因此,是的,我们通过使用方便的“并行运行”标志在VST中并行运行测试,但这还不够,我们必须将测试分成单独的测试项目。当然,逻辑上分组,而不是每个测试都有一个项目,这将是荒谬的
确保DataTable中的第一列是唯一的Id
创建接受DataRow但不返回任何内容的AsyncExecutionTask委托
使用接受DataRow和AsyncExecutionTask委托的AsyncExecutionContext方法创建静态类(并行测试)
在静态类中添加静态BatchStarted属性
在静态类中添加静态AsyncExecutionTests字典属性
在AsyncExecutionContext方法中添加以下内容:
public static void AsyncExecutionContext(DataRow currentRow, AsyncExecutionTask test)
{
if(!BatchStarted)
{
foreach(DataRow row in currentRow.Table)
{
Task testTask = new Task(()=> { test.Invoke(row); });
AsyncExecutionTests.Add(row[0].ToString(), testTask);
testTask.Start();
}
BatchStarted = true;
}
Task currentTestTask = AsyncExecutionTests[row[0].ToString()];
currentTestTask.Wait();
if(currentTestTask.Exception != null) throw currentTestTask.Exception;
}
现在像这样使用类:
[TestMethod]
public void TestMethod1()
{
ParallelTesting.AsyncExecutionContext(TestContext.DataRow, (row)=>
{
//Test Logic goes here.
}
);
}
注意:您必须对异常进行一些修补,以使它们正确冒泡(这里可能有一个聚合异常,您需要它的第一个异常)。每个测试执行所需的显示时间将不再准确。您还需要在最后一行完成后清理ParallelTesting类
工作原理:测试逻辑被包装在lambda中,并传递给静态类,该类将在第一次调用(第一行执行)时为每行测试数据执行一次逻辑。对静态类的连续调用只需等待预启动的测试任务完成即可
通过这种方式,测试框架对TestMethod的每次调用都会简单地收集已经运行的相应测试的测试结果
可能的改进:
- 使AsyncExecutionContext接受maxSynchronousTasks参数
- 查看框架如何跨非托管代码移动完整的stacktrace,以查看Task.Exception是否可以传递给visual studio测试框架,而无需重新刷新和销毁stacktrace
本页上的大多数答案都忘了提到MSTest在单独的程序集中并行测试。您必须将unittests拆分为多个.dll以并行化它
但是!最新版本mstestv2-now可以并行化“in-assembly”(耶!)您只需要在您的测试项目中安装几个nuget软件包-TestFramework和TestAdapter-如这里所述
然后简单地将其添加到您的测试项目中
[assembly: Parallelize(Workers = 4, Scope = ExecutionScope.ClassLevel)]
编辑:您还可以使用[DoNotParallelize]禁用特定测试的并行执行
关于测试方法。你在这里谈论的是1000个线程。对,我想知道是否有一个预构建框架来管理这个。或者如果有人构建他们自己的框架。你需要一个负载模拟器。MSTest不是用来做负载测试的。顺便说一句,1000个线程是疯狂的,你需要做的是研究不同的测试技术,这超出了单元测试的范围。我不想执行负载测试。VS有一个很好的模块。我只想并行运行单元测试。好吧,1000太多了?100:)重复的是,刚刚发现困难的方法:)-我在8核上运行了我的套件,所有测试都被中止了…它不应该总共被限制为5个,但是有5个测试挂起。Bruce Taimana的评论:“如果清理“挂起”或需要太长时间,我们让它继续清理,但我们同时启动下一个测试。如果你达到5