并行测试
TeamCity 现在能够通过在多个构建代理之间分配来并行执行您的测试,从而最大限度地减少测试的总体持续时间。 构建的测试可以自动分割成批次,每个批次将在单独的构建代理上运行。 此功能解决了一个常见的使用案例,即构建在同一代理上连续运行许多独立测试,尽管从技术上讲,它们可以并行运行,利用多个代理的资源。 以前,为了模拟这种行为,一些用户会配置多个构建配置,并通过平行连接将它们连接成链。 这种方法可行,但有时需要实施非常规的逻辑,将测试分布到多个批次中。
在 TeamCity 2022.04 中,测试的分发逻辑由 TeamCity 本身提供。 此外,诸如 Maven、Gradle、IntelliJ IDEA Project以及.NET这样的构建运行程序能够在代理上自动过滤测试,而无需更改构建步骤的设置。
并行运行测试
新的 Parallel tests 构建功能解决了在不同代理上并行测试执行的任务。 要在已配置为运行带有测试的构建步骤的现有构建配置中启用此功能,请转到 Build Configuration Settings | Build Features,点击 Add build feature,然后选择 Parallel tests 类型。 您将被提示设置批次数量,这也意味着在构建中要使用的并行代理的数量。
在 TeamCity 将测试分批并行运行之前,它需要收集至少一次前置构建的测试统计信息。 这些信息有助于将测试划分为几乎等大的批次(基于测试持续时间),以便总的构建时间尽可能短。 如果您在新添加的构建配置中启用此功能,那么它的第一个构建将以正常模式运行;当它完成并生成测试报告时,TeamCity 将能够分割第二个。
TeamCity 不仅考虑最近一次的测试运行,而且也会考虑您的测试历史:后续的并行测试构建也将为这个统计数据做出贡献,并让 TeamCity 做出更明智的决定。
内部运作
如果测试统计信息可用,那么在触发新的构建时,会发生以下情况:
TeamCity 根据构建功能中指定的批次数量,生成当前构建配置的副本。 这些构建配置将拥有与原始配置相同的构建步骤。 在未来,原始配置的构建步骤的更改将会自动传播到生成的配置中。
触发的构建将转变为依赖于生成的构建配置中的构建的 composite build。
一旦开始进行第一个依赖性构建,组合构建也将开始。
生成的构建配置的构建将运行与原始构建配置中定义的相同的构建步骤集。 如果这些步骤中的一部分是 Maven、Gradle、IntelliJ IDEA Project 或 .NET 类型,并且他们正在执行一些测试,那么这些构建运行程序将自动运行仅与当前批次相对应的测试的一部分。
如果您以不同的方式运行测试,您仍然可以为您的配置启用 并行测试 构建功能,从而受益于自动化测试划分:您将从 构建参数 中获取执行测试的信息,这些参数将由构建功能提供。
特定于 Runner 的要求
只有满足以下要求,才支持自动执行一批测试,而不是执行所有测试:
自定义并行化测试的执行
在某些情况下,测试以 TeamCity 无法以任何方式影响其执行的方式进行。 例如,它们可以实时生成,或者可以由第三方构建运行程序报告,或者从文件中导入,等等。
在这种情况下,用户需要实现自定义测试执行逻辑,以执行仅一个测试批次。 并行测试 构建功能通过提供一系列构建参数,简化了任务。 这些参数是:
形参名称 | 描述 |
---|---|
teamcity.build.parallelTests.currentBatch | 包含从1开始的当前批次编号 |
teamcity.build.parallelTests.totalBatches | 包含已配置批次的总数 |
system.teamcity.build.parallelTests.excludesFile | 包含代理上的路径,该路径指向一个文本文件,其中的测试应该从执行中排除 |
被排除测试的文件格式如下:
这里的 版本
代表文件格式版本。 暗含着自定义测试的执行逻辑会检查版本,并在版本具有意外值时报告错误或失败构建。
在未来,新的以 #
字符开头的关键词可以被添加到该文件中。 所有此类未识别的关键词应被忽略。
注意:Java 和 .NET 测试框架通常会以以下格式向 TeamCity 报告测试:
[<套件名称>: ]<完全限定的测试类名称>.<测试方法>[<测试参数>]
在这里, <suite name>
和 <test arguments>
是可选项,并不总是出现。
例如,以下的 Java 测试类:
将在 TeamCity 中生成以下测试名称:
那么参数 system.teamcity.build.parallelTests.excludesFile
将指向一个包含以下内容的文本文件:
具有自定义测试执行逻辑的构建步骤应使用此文件,并过滤掉所有属于其中提到的类的测试。 所有其他测试都应该执行。
.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 标签页中显示。 这种行为适用于构建步骤生成的构件配置,但不适用于生成相似文件集的并行任务。
为了获取所有并行任务的工件(例如,当您的每个测试生成 "report.log" 文件时),在为父构建配置定义工件路径时,请使用 teamcity.build.parallelTests.currentBatch
参数。 由于此参数引用了批处理构建编号,因此它允许构建将其工件组织到具有唯一名称的子目录中。 例如:
已知的限制
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。
并行测试的后续构建不会重复使用已有的生成构建配置的构建,即使没有新的 VCS 提交。
批处理构建是为了运行 TestNG 从一个 XML套件 中的测试,而不是运行指定的测试子集。 相关的 YouTrack 工单:TW-75849。