TeamCity On-Premises 2025.07 Help

并行测试

TeamCity 现在能够通过在多个构建代理之间分配来并行执行您的测试,从而最大限度地减少测试的总体持续时间。 构建的测试可以自动分割成批次,每个批次将在单独的构建代理上运行。 此功能解决了一个常见的使用案例,即构建在同一代理上连续运行许多独立测试,尽管从技术上讲,它们可以并行运行,利用多个代理的资源。 以前,为了模拟这种行为,一些用户会配置多个构建配置,并通过平行连接将它们连接成链。 这种方法可行,但有时需要实施非常规的逻辑,将测试分布到多个批次中。

在 TeamCity 2022.04 中,测试的分发逻辑由 TeamCity 本身提供。 此外,诸如 MavenGradleIntelliJ IDEA Project以及 .NET这样的构建运行程序能够在代理上自动过滤测试,而无需更改构建步骤的设置。

并行运行测试

并行测试构建功能解决了在不同代理上执行并行测试的任务。

要在现有构建配置中启用此功能:

  1. 打开 配置设置并导航到 构建功能设置选项卡。

  2. 点击 添加构建功能 并选择 并行测试类型。

  3. 设置测试批次的数量,这也意味着在构建中使用的并行代理数量。

在 TeamCity 将测试分批并行运行之前,它需要收集至少一次前置构建的测试统计信息。 这些信息有助于将测试划分为几乎等大的批次(基于测试持续时间),以便总的构建时间尽可能短。 如果您在新添加的构建配置中启用此功能,那么它的第一个构建将以正常模式运行;当它完成并生成测试报告时,TeamCity 将能够分割第二个。

TeamCity 不仅考虑最近一次的测试运行,而且也会考虑您的测试历史:后续的并行测试构建也将为这个统计数据做出贡献,并让 TeamCity 做出更明智的决定。

内部运作

如果测试统计信息可用,那么在触发新的构建时,会发生以下情况:

  1. TeamCity 根据构建功能中指定的批次数量,生成当前构建配置的副本。 这些构建配置将拥有与原始配置相同的构建步骤。 在未来,原始配置的构建步骤的更改将会自动传播到生成的配置中。

  2. 触发的构建将转变为依赖于生成的构建配置中的构建的 composite build

  3. 一旦开始进行第一个依赖性构建,组合构建也将开始。

生成的构建配置的构建将运行与原始构建配置中定义的相同的构建步骤集。 如果这些步骤中的某些是 MavenGradleIntelliJ IDEA 项目.NET类型,并且它们正在执行一些测试,那么这些构建运行器将自动仅运行与当前批次对应的测试部分。

如果您以不同的方式运行测试,您仍然可以为您的配置启用 并行测试构建功能并从自动测试划分中受益:您将从 构建参数中获取有关要执行的测试的信息,这些参数将由构建功能提供。

特定于 Runner 的要求

只有满足以下要求,才支持自动执行一批测试,而不是执行所有测试:

  • Maven

    • Maven 最低支持版本:3.x。

    • Maven Surefire 插件最低支持版本:2.13。

    • Maven Failsafe 插件支持的最小版本:2.13。

  • Gradle

    • Gradle 最低支持版本:5.0。

  • .NET

    • Microsoft.NET.Test.Sdk 最低支持版本:16.0。

自定义并行化测试的执行

在某些工作流中,TeamCity 无法将测试拆分为批次,因为它无法控制测试的执行。 例如,当测试是动态生成的、由自定义构建步骤报告的,或从文件中导入的。

即便如此,TeamCity 仍会跟踪已执行的测试并分析之前的运行,以计算最佳的批次分布。 这些数据可通过以下参数获取:

  • teamcity.build.parallelTests.currentBatch — 当前批次号(从 1 开始)。

  • teamcity.build.parallelTests.totalBatches — 批次数总数。

  • system.teamcity.build.parallelTests.excludesFile — 代理机器上 excludesFile.txt 文件的路径,该文件存储了 currentBatch 运行时应禁用哪些测试的信息。

要并行运行测试,请实现一个自定义机制(例如测试框架扩展或构建步骤),该机制读取这些参数并禁用不属于当前批次的测试。

excludesFile 文件由 TeamCity 服务器生成,不应手动修改。 此文件具有以下格式:

#version=<value> #algorithm=<value> #current_batch=<value> #total_batches=<value> #suite=<value1> #suite=<value2> ... <newline-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

.NET 的备选测试过滤器

如果 .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 将来自单个批次的构件聚合到主配置构建中。

聚合艺术品图表

当批量构建生成相同的工件时,只有最新批量构建的工件会在父配置的 Artifacts 标签页中显示。 如果所有这些文件都相关并且应从主构建中可见,请启用 Parallel Test 功能的 工件 设置。

object Build : BuildType({ name = "Build" artifactRules = ".teamcity/Paralleltests/buildTypes => artifacts" // ... features { parallelTests { numberOfBatches = 2 separateArtifacts = true } } })

这样做可以让 TeamCity 在主配置构建中聚合批次输出时,将其放入“Batch N”文件夹中。

单独批次文件夹中的构件

您可以通过将 参数 添加到构件路径中来实现自定义分组逻辑。 每个批次的参数应具有唯一的值。 例如,添加 teamcity.build.parallelTests.currentBatch 参数会生成与上述 Parallel Tests 功能设置类似的结果。

object Build : BuildType({ name = "Build" artifactRules = "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 版本中的构建配置限制而言,自动生成的构建配置会被视为正常的构建配置。

已知的错误

最后修改日期: 2025年 9月 3日