并行测试
TeamCity 现在能够通过在多个构建代理之间分配来并行执行您的测试,从而最大限度地减少测试的总体持续时间。 构建的测试可以自动分割成批次,每个批次将在单独的构建代理上运行。 此功能解决了一个常见的使用案例,即构建在同一代理上连续运行许多独立测试,尽管从技术上讲,它们可以并行运行,利用多个代理的资源。 以前,为了模拟这种行为,一些用户会配置多个构建配置,并通过平行连接将它们连接成链。 这种方法可行,但有时需要实施非常规的逻辑,将测试分布到多个批次中。
在 TeamCity 2022.04 中,测试的分发逻辑由 TeamCity 本身提供。 此外,诸如 Maven、 Gradle、 IntelliJ IDEA Project以及 .NET这样的构建运行程序能够在代理上自动过滤测试,而无需更改构建步骤的设置。
并行测试构建功能解决了在不同代理上执行并行测试的任务。
要在现有构建配置中启用此功能:
打开 配置设置并导航到 构建功能设置选项卡。
单击 添加构建功能 并选择 并行测试类型。
设置测试批次的数量,这也意味着在构建中使用的并行代理数量。
tip
注意:只有来自不同类(或测试用例)的测试方法可以在不同的代理上并行运行。
在 TeamCity 将测试分批并行运行之前,它需要收集至少一次前置构建的测试统计信息。 这些信息有助于将测试划分为几乎等大的批次(基于测试持续时间),以便总的构建时间尽可能短。 如果您在新添加的构建配置中启用此功能,那么它的第一个构建将以正常模式运行;当它完成并生成测试报告时,TeamCity 将能够分割第二个。
TeamCity 不仅考虑最近一次的测试运行,而且也会考虑您的测试历史:后续的并行测试构建也将为这个统计数据做出贡献,并让 TeamCity 做出更明智的决定。
如果测试统计信息可用,那么在触发新的构建时,会发生以下情况:
TeamCity 根据构建功能中指定的批次数量,生成当前构建配置的副本。 这些构建配置将拥有与原始配置相同的构建步骤。 在未来,原始配置的构建步骤的更改将会自动传播到生成的配置中。
触发的构建将转变为依赖于生成的构建配置中的构建的 composite build。
一旦开始进行第一个依赖性构建,组合构建也将开始。
tip
原始构建配置的设置不受 并行测试 构建功能的影响。
另一方面,生成的构建配置的数量和设置完全由 并行测试 构建功能进行控制。 生成的构建配置默认为只读,不建议手动修改。 生成的构建配置也被放置在一个隐藏的子项目中。 如果项目启用了 版本设置 ,生成的构建配置将不会提交给 VCS 仓库。
生成的构建配置的构建将运行与原始构建配置中定义的相同的构建步骤集。 如果这些步骤中的某些是 Maven、 Gradle、 IntelliJ IDEA 项目或 .NET类型,并且它们正在执行一些测试,那么这些构建运行器将自动仅运行与当前批次对应的测试部分。
tip
如果原始构建配置包含部署步骤,则这些步骤将执行的次数与批次数相同。
如果您以不同的方式运行测试,您仍然可以为您的配置启用 并行测试构建功能并从自动测试划分中受益:您将从 构建参数中获取有关要执行的测试的信息,这些参数将由构建功能提供。
只有满足以下要求,才支持自动执行一批测试,而不是执行所有测试:
在某些情况下,测试以 TeamCity 无法以任何方式影响其执行的方式进行。 例如,它们可以实时生成,或者可以由第三方构建运行程序报告,或者从文件中导入,等等。
在这种情况下,用户需要实现自定义测试执行逻辑,以执行仅一个测试批次。 并行测试 构建功能通过提供一系列构建参数,简化了任务。 这些参数是:
形参名称 | 描述 |
---|---|
teamcity.build.parallelTests.currentBatch | 包含从1开始的当前批次编号 |
teamcity.build.parallelTests.totalBatches | 包含已配置批次的总数 |
system.teamcity.build.parallelTests.excludesFile | 包含代理上的路径,该路径指向一个文本文件,其中的测试应该从执行中排除 |
excludesFile
文件由 TeamCity 服务器生成,不应手动修改。 相反,您应该读取其内容以实现您自己的自定义测试执行逻辑。 此文件具有以下格式:
#version=<value>
#algorithm=<value>
#current_batch=<value>
#total_batches=<value>
#suite=<value>
<new line separated list of test classes>
- 版本
一个整数值,表示文件格式版本。 假定自定义测试执行逻辑会检查版本,并在版本值不符合预期时报告错误或使构建失败。
- 算法
负责将测试分解为批次的算法类型。 可用值:
DURATION
— 优先考虑测试类的执行时间作为创建运行时间大致相等的批次的主要指标。SPLIT_SUITE
— 将测试套件中的每个测试类分成 N 个批次。GROUP_SUITES
— 与DURATION
相同,但将同一套件中的所有测试分组到一个批次中,忽略单个测试类。
- current_batch
当前批次的编号,与
teamcity.build.parallelTests.currentBatch
参数相同。- total_batches
批次总数,与
teamcity.build.parallelTests.totalBatches
参数相同。- 套件
测试套件名称。 此参数可以为空值。
注意:Java 和 .NET 测试框架通常会以以下格式向 TeamCity 报告测试:
[<套件名称>: ]<完全限定的测试类名称>.<测试方法>[<测试参数>]
在这里, <suite name>
和 <test arguments>
是可选项,并不总是出现。
例如,以下的 Java 测试类:
package org.example.tests;
class TestCase1 {
public void testMethod1() { /* ... */ }
public void testMethod2() { /* ... */ }
}
将在 TeamCity 中生成以下测试名称:
org.example.tests.TestCase1.testMethod1
org.example.tests.TestCase1.testMethod2
那么参数 system.teamcity.build.parallelTests.excludesFile
将指向一个包含以下内容的文本文件:
#version=1
#current_batch=1
#total_batches=3
#suite=
org.example.tests.TestCase1
tip
注意:测试过滤的粒度是以类(或测试用例)为单位,而非测试方法。
具有自定义测试执行逻辑的构建步骤应使用此文件,并过滤掉所有属于其中提到的类的测试。 所有其他测试都应该执行。
如果 .NET 运行程序处理大量的测试类,那么并行测试可能会产生难以解析和被 NUnit 这样的测试引擎使用的大量测试过滤器。
为避免可能的性能问题,TeamCity 会自动采用一种针对这些情况优化的替代测试过滤模式。 如果满足以下条件,则可以按每个代理基础启用此模式:
运行测试批次的代理报告 .NET CLI (SDK 或运行时)6.0 或更新版本。
一个测试批次有1000个或更多的测试类。 您可以通过
teamcity.internal.dotnet.test.suppression.test.classes.threshold
配置参数 更改此阈值。
您可以阻止 TeamCity 切换到此模式,并强制其始终在任何个别项目或构建配置中使用常规筛选机制来运行并行 .NET 测试。 为了实现这一目标,将 teamcity.internal.dotnet.test.suppression=false
参数 添加到所需的配置或项目中。
由于并行测试在独立的批处理构建中运行,由这些批处理构建执行的实际构建例程,而不是由父配置的构建,会生成 artifacts。
然而,TeamCity 会将批处理构建生成的工件在父配置构建中进行聚合,以便可以从一个地方轻松访问。

当批次构建生成相同的工件时,仅显示最新批次构建的工件在父配置的 工件 选项卡中。 这种行为适用于构建步骤生成的构件配置,但不适用于生成相似文件集的并行任务。
为了获取所有并行任务的工件(例如,当您的每个测试生成 "report.log" 文件时),在为父构建配置定义工件路径时,请使用 teamcity.build.parallelTests.currentBatch
参数。 由于此参数引用了批处理构建编号,因此它允许构建将其工件组织到具有唯一名称的子目录中。 例如:
bin => batch-build-%\teamcity.build.parallelTests.currentBatch%/bin

始终运行新构建 行为(快照依赖如果有合适的构建,则不要运行新构建 设置已禁用)仅影响主配置构建。 当使用 并行测试 功能时,动态生成的虚拟构建配置可能仍会重用其先前的结果。 如果未检测到新的存储库提交,则只有先前失败的测试批次会运行新的构建,而成功的批次会被重用。
在下图中,“Composite Conf”配置依赖于“Maven App”配置。 后者以两个并行批次运行其测试。 请注意,主“Maven app”构建 #18 被重新触发,而动态生成的“Maven app 1”配置重用了其先前成功的构建(#12)。

您可以强制 TeamCity 重新运行所有虚拟配置构建。 在这种情况下,即使未发现新的存储库提交,每个单独的测试批次也会重新运行。

为此,请将 teamcity.internal.splitBuild.dependency.takeStartedBuildWithSameRevisions=false
参数 添加到具有并行测试功能的配置中。
要将此行为应用于服务器上的所有配置,请将此参数添加到 内部属性 列表中。
Code coverage统计在并行测试的构建中可能会不准确,因为它将为当前批次执行的部分测试收集数据。
一项尚未被 TeamCity 所知的新测试将在首次运行期间的每一批次中运行。 相关的 YouTrack 工单: TW-75913。
当 TeamCity 将测试划分为批次时,它只考虑到了测试本身的持续时间。 setUp / tearDown 或任何其他准备方法的持续时间,TeamCity 并不知道,因此批次的持续时间可能并不相等。
在自定义构建对话框中选择的代理将被忽略,因为触发后,构建将转变为一个复合构建来进行并行测试。 相关的 YouTrack 工单: TW-74905。
通过 setParameter 服务消息发布的构建步骤参数,以及运行器特定参数如
maven.project.version
,在并行测试的复合构建中将不可用。 相关的 YouTrack 工单: TW-75249。就 TeamCity Professional 版本中的构建配置限制而言,自动生成的构建配置会被视为正常的构建配置。
Enforce Clean Checkout action 不适用于配置了并行测试的构建配置。 相关的 YouTrack 工单: TW-75337。
批处理构建是为了运行 TestNG 从一个 XML套件 中的测试,而不是运行指定的测试子集。 相关的 YouTrack 工单: TW-75849。
Thanks for your feedback!