亚马逊AWS官方博客

使用 AWS CodeBuild 加速 CI:现已支持并行测试!

我很高兴向大家宣布,AWS CodeBuild 现在支持并行测试,因此在运行测试套件的同时,构建时间也会明显地缩短。

在我为这篇文章编写的演示项目中,总测试时间从 35 分钟缩短到了 6 分钟,其中还包括预置环境的时间。下面这两张来自 AWS 管理控制台的屏幕截图显示了有关时间的差异。

测试套件的顺序执行

CodeBuild 并行测试结果

测试套件的并行执行

CodeBuild 并行测试结果

大规模运行持续集成(CI)时,如果测试时间太长,则会带来非常严重的挑战。随着项目的复杂性和项目团队规模的不断增加,执行综合测试套件所需的时间可能会急剧增加,从而导致管道执行时间被延长。这不仅会延迟新功能和错误修复的交付,还会迫使开发人员在拿到构建结果后才能继续执行任务,从而对他们的生产力造成负面影响。我曾经就体验过一个类似的情况,当时管道需要长达 60 分钟才能运行,但在最后一步却失败了,整个过程都需要完全重新运行一遍,整个任务进一步被延迟。这些漫长的周期会削弱开发人员对 CI 流程的信任度,加剧挫败感,并最终延缓整个软件交付周期。此外,运行时间太长的测试可能导致资源争用,因计算能力浪费而增加成本,并会降低开发过程的整体效率。

通过在 CodeBuild 中执行并行测试,您现在可以在多个构建计算环境中并行运行测试。此功能实现了一种分片方法,即每个构建节点独立执行测试套件的一个子集。CodeBuild 提供环境变量来标识当前节点数和节点总数,这些值用于确定每个节点应运行哪些测试。在构建时,节点之间没有控制构建节点或协调 – 每个节点独立运行以执行为其分配的那一部分测试。

要启用测试拆分,请在 buildspec.xml 中配置 batch fanout 部分,指定所需的并行性级别和其他相关参数。此外,在构建步骤中使用 codebuild-tests-run 实用程序,以及相应的测试命令和所选的拆分方法。

测试将根据您指定的分片策略进行拆分。codebuild-tests-run 提供了两种分片策略:

  • 均等分配。 此策略按字母顺序对测试文件进行排序,并将它们按块平均地分发到并行测试环境中。测试文件名称或数量的更改可能会导致在分片之间重新分配文件。
  • 稳定性。 此策略通过使用一致的哈希算法来修复分片间测试的分布。当添加或删除新文件时,它会保留现有的文件到分片的分配方式。

CodeBuild 支持在并行运行测试时自动合并测试报告。通过自动合并测试报告,CodeBuild 将测试报告合并为单份测试摘要,从而简化了结果分析过程。合并后的报告包括汇总的合格/失败状态、测试持续时间和失败详情,从而减少了不必要的手动报告处理。您可以在 CodeBuild 控制台中查看合并后的结果,使用 AWS 命令行界面(AWS CLI) 检索结果,或者将结果与其他报告工具集成以简化测试分析。

工作原理

我来给大家演示如何在项目中实现并行测试。在这个演示中,我创建了一个非常基本的 Python 项目,其中包含数百个测试。为了加快速度,我在命令行上让 Amazon Q 开发者版创建了一个项目和 1800 个测试用例。每个测试用例都位于一个单独的文件中,需要一秒钟才能完成。按顺序运行所有测试需要 30 分钟,这不包括预置环境的时间。

在本演示中,我在 10 个计算环境上并行运行测试套件,并测量运行该测试套件所需的时间。

为此,我在我的项目中添加了一个 buildspec.yml 文件。

version: 0.2

batch:
  fast-fail: false
  build-fanout:
    parallelism: 10 # ten runtime environments 
    ignore-failure: false

phases:
  install:
    commands:
      - echo 'Installing Python dependencies'
      - dnf install -y python3 python3-pip
      - pip3 install --upgrade pip
      - pip3 install pytest
  build:
    commands:
      - echo 'Running Python Tests'
      - |
         codebuild-tests-run \
          --test-command 'python -m pytest --junitxml=report/test_report.xml' \
          --files-search "codebuild-glob-search 'tests/test_*.py'" \
          --sharding-strategy 'equal-distribution'
  post_build:
    commands:
      - echo "Test execution completed"

reports:
  pytest_reports:
    files:
      - "*.xml"
    base-directory: "report"
    file-format: JUNITXML 
YAML

YAML 文件中有三个部分需要重点介绍。

首先,batch 下有一个 build-fanout 部分。parallelism 命令告诉 CodeBuild 有多少测试环境需要并行地运行。ignore-failure 命令指示是否可以忽略任何 fanout 构建任务中的失败。

其次,我使用预安装的 codebuild-tests-run 命令来运行我的测试。

此命令接收测试文件的完整列表,并决定哪些测试必须在当前节点上运行。

  • 如上所述,使用 sharding-strategy 参数在均等分布或稳定分布之间进行选择。
  • 使用 files-search 参数传递所有作为运行候选的文件。出于性能原因,我们建议使用所提供的 codebuild-glob-search 命令,但也可以使用任何其他文件搜索工具(例如 find (1))。
  • 我通过 test-command 参数传递在分片上运行的实际测试命令。

最后,reports 部分指示 CodeBuild 收集并合并每个节点上的测试报告。

然后,我打开 CodeBuild 控制台创建一个项目,并为该项目创建批量构建配置。这里没有什么新内容,所以我就不赘述细节了。该文档包含入门所需的所有详细信息。  并行测试适用于批量构建。确保将您的项目配置为批量运行

CodeBuild:创建批量构建

现在,我已经准备好触发测试套件的执行了。我可以在我的 GitHub 存储库上提交新代码,或在控制台中触发构建。

CodeBuild:触发新构建

几分钟后,我将看到构建的不同步骤的状态报告;其中包含每个测试环境或分片的状态。

CodeBuild:状态

测试完成后,我选择报告选项卡来访问合并的测试报告。

CodeBuild:测试报告

报告部分汇总了来自所有分片的所有测试数据,并保留了所有构建的历史记录。我在报告历史记录部分中选择我的最新构建来访问详细报告。

CodeBuild:测试报告

正如预期的那样,我可以看到 1800 个测试用例中每个测试用例的汇总状态和单独状态。在这个演示中,它们都通过了测试,报告显示为绿色。

该演示项目中的 1800 个测试各需要一秒钟才能完成。当我按顺序运行这个测试套件时,花了 35 分钟才完成。当我在 10 个计算环境上并行运行测试套件时,花了 6 分钟就完成了测试,包括预配环境的时间。并行运行时间只有连续运行时间的 17.1%。实际数字将因您的项目差异而有所不同。

其他事项

这项新功能与所有测试框架兼容。该文档包括 Django、Elixir、Go、Java(Maven)、Javascript(Jest)、Kotlin、PHPUnit、Pytest、Ruby(Cucumber)和 Ruby(RSpec)的示例。

对于不接受空格分隔列表的测试框架,codebuild-te sts-run CLI 通过 CODEBUILD_CURRENT_SHARD_FILES 环境变量提供了一种灵活的替代方案。此变量包含当前构建分片的测试文件路径的换行符分隔列表。您可以用它来适配不同的测试框架要求和格式化测试文件名。

您可以通过编写自己的分片脚本并使用 CODEBUILD_BATCH_BUILD_IDENTIFIER 环境变量(该变量在每个构建中自动设置)来进一步自定义跨环境拆分测试的方式。您可以使用此技术来实现特定于框架的并行化或优化。

定价和可用性

通过并行测试执行,您现在可以在很短的时间内完成测试套件,其所需时间只是先前所需时间的一小部分,从而加快开发周期并提高团队的产出。对于为了阐述这篇文章而创建的演示项目,它仅用了顺序构建测试时间的 18.7% 就完成了整个测试过程。

CodeBuild 提供的所有三种计算模式均支持并行测试执行:按需计算、预留容量和 AWS Lambda 计算。

目前,所有提供 CodeBuild 的 AWS 区域均可使用该功能,除了所用计算资源的标准 CodeBuild 定价外,没有其他费用。

今天,我邀请大家尝试在 CodeBuild 中执行并行测试。访问 AWS CodeBuild 文档以了解更多信息,并开始并行执行您的测试。

— seb

PS:这是我在创建演示应用程序及其测试套件时使用的提示词:“我正在写一篇博客文章来宣布 CodeBuild 并行测试的发布。编写一个非常简单的 python 应用程序,它有数百个测试,每个测试都位于一个单独的测试文件中。每个测试都需要一秒钟才能完成。”


*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您了解行业前沿技术和发展海外业务选择推介该服务。