【问题标题】:Continuous integration: ensure new commits are covered with tests持续集成:确保新的提交被测试覆盖
【发布时间】:2013-03-25 14:14:57
【问题描述】:

我正在处理一个项目,该项目包含大量未包含在测试中的遗留代码。

我有什么方法可以设置集成服务器来检查所有新提交是否具有最少的测试量(例如,覆盖率 >70%)?

基本上,我看到了两个选项:

  1. 当提交的更改未包含在单元测试中时,以某种方式设置 CI 服务器以使构建失败。这将确保每段新代码都有测试,并且旧代码的测试会随着每次更改而增加。
  2. 为整个项目设置覆盖阈值,如果在提交后覆盖百分比降低,则构建失败。这样做的问题是,如果我删除一个包含 100 条指令的类并添加一个包含 50 条指令的新类,那么覆盖率就会上升,而无需我编写任何测试。

我更喜欢选项 1,因为它强制对遗留代码的更改进行单元测试。这应该会增加整体测试覆盖率。

现在我们使用 Jenkins 作为 CI 服务器,使用 JaCoCo 进行测试覆盖。 Maven 用于构建项目,SVN 是我们的主要源代码控制。

【问题讨论】:

  • 请记住,100% 的覆盖率不一定是可能的,甚至是不希望的。覆盖数字也可以被操纵;为测试类编写单元测试会人为地扩大测试覆盖率。
  • @MikeRylander 我知道,我什至不梦想 100% 覆盖这个项目。但我仍然认为强制新的更改至少有一些覆盖面是好的。
  • 我目前正在努力解决这个问题,主要解决@MikeRylanders 的评论。 pitest.org 现在与版本控制集成。下一个版本将允许通过 scm 状态分析文件。以下版本将允许按日期范围或提交进行分析,这将允许构建服务器检查修改后的代码是否满足给定的突变分数。
  • @henry 感谢您的链接。听起来很棒,我会试一试。直到现在才听说过突变测试。因为你,我将在接下来的几天里阅读 wiki、常见问题解答和热门话题。谢谢;)
  • @DenisRosca 突变测试确实很棒 - 请注意它非常占用 CPU,因此您需要仔细考虑如何使用它。

标签: java jenkins continuous-integration code-coverage jacoco


【解决方案1】:

我知道您可以配置 Jenkins 以验证至少有一个测试文件作为提交的一部分。这不能保证良好的测试覆盖率,但至少您会知道存在某种与测试相关的更改。

【讨论】:

  • 我不喜欢这个主意。如果您正在提交某些内容以使之前失败的测试通过,则不需要同时提交测试文件。
  • @JohnnyO 理论上一个失败的构建不应该首先被提交。除非您的单元测试不稳定或与外部依赖关系相关,这是一组不同的问题,否则您永远不必提交修复损坏的单元测试。
  • 理论上,当然。在实践中,并没有那么多。假设您有一个错误的提交(假设您忘记包含一个文件)。因此,测试在本地通过,但在 Jenkins 中失败。在这种情况下,您将如何提交丢失的文件?
  • @JohnnyO 您可以将强制/覆盖逻辑添加到您的提交挂钩中。这种方法为添加测试提供了快速反馈,但如果用户真的想忽略这样的警告,他们总能找到一些方法。
【解决方案2】:

一些覆盖工具(如 cobertura)支持排除包。这样,您可以排除所有旧代码(假设它可以进行模式匹配)并让 cobertura 仅检查新代码(涵盖新提交)。

我希望这会有所帮助。

【讨论】:

  • 感谢您的意见,但我的目标是确保测试新代码并强制对旧代码进行更改。
【解决方案3】:

对于选项 2,您可以使用 Jenkins JaCoCo plugin 跟踪每个构建的代码覆盖率,并根据覆盖率指标将构建结果设置为通过或失败。

我也更喜欢选项 1,但我不知道 Jenkins 有什么内置方法可以做到这一点。对覆盖数据进行后处理并将其与 SVN 修订信息结合起来应该相当容易(至少在类级别),例如:

  1. 解析 JaCoCo 输出文件并查找覆盖率为 0% 的类
  2. 从 SVN 修订详细信息获取为此构建更改的文件(Jenkins 使修订号在环境变量中可用,如果此构建只有一个,则为 SVN_REVISION 或 SVN_REVISION_1、SVN_REVISION_2、... 多个)
  3. 如果任何更改的类的覆盖率为 0%,则打印错误消息
  4. 如果打印错误消息,请使用 Jenkins Text Finder plugin 使构建失败。

这不是一个完整的解决方案,它对于测试未涵盖的新方法或行变得更加棘手。给了我一个新的 Jenkins 插件的想法;-)

【讨论】:

  • 但是如果提交的更改没有包含在测试中,我该如何配置这个插件失败?如果我在旧文件中添加一个小更改,这可能不会改变整体覆盖率指标,因此不会导致构建失败?
  • 对,这就是为什么我将我的 cmets 包括在您的第一个选项中。
  • 我会焦急地等待你的插件。
【解决方案4】:

我已经建立了一个工具,正是这样做的

https://github.com/exussum12/coverageChecker

你传入分支的差异和测试的覆盖测试输出。该工具可以确定 diff 中的哪些行也在 clover 文件中。如果低于一定百分比,则构建失败

使用

bin/diffFilter --phpunit diff.txt clover.xml 70

当测试覆盖不到 70% 的差异时,构建失败

如果需要,我可以添加其他格式

编辑

我已经加了jacoco

Bin/diffFilter --jacoco diff.txt jacoco.xml

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-24
    • 2016-06-15
    • 2013-10-14
    相关资源
    最近更新 更多