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