第二十四天:使用 TeamCity 监看覆盖率变化

昨天我们在 Build Step 里开启 Coverage 的功能,让 TeamCity 在运行测试後一并产生覆盖率报告,方便我们了解程序码库的状态及趋势。不过实务上来说,大概很少人会每一个 Build Log 都点进去看覆盖率报告。对於开发者来说,与其说在意覆盖率的「数值」,更在意的是覆盖率的「变化」。

TeamCity 的 Failure Condition 设计

在软件测试领域,有一种作法叫「童子军原则」,对於童子军来说,「离开营地前,让营地比使用前更加乾净」;而对开发者来说,「提交程序码後,至少不能让覆盖率往下掉」。所以若是 TeamCity 能在覆盖率数值降低时直接视为建置失败,主动通知我们,是不是就能变成某种形式的品质控管,多一只眼睛帮我们监看着?

TeamCity 的确有考量到这个需求,设计了称为 Failure Condition 的功能。简单来说,我们可以为 Build 设定失败条件,这个条件的形式很多,可以是 Build 过程中有错误讯息,也可以是 Build 的时间过久、Crash、记忆体超载。或是跟数值有关,比方说覆盖率低於多少、产生来的成品档案超过大小、Inspection 错误的数量多於多少…等。只要这个条件一发生,即便建置任务有完成,这次的建置工作也算失败。而当建置失败时,TeamCity 就会主动通知我们,满足我们需要监看品质的需求。

先故意降低程序码库的覆盖率

为了要示范 TeamCity Failure Condition 的功能,我们先故意降低程序库的覆盖率。降低的方式很简单,我们在 ShoppingCart 这个类别里新增几个方法,但都故意不写测试。这样程序码的数量增加了,但测试没有跟着测试到,整体的覆盖率就会降低了。

首先打开 ShoppingCart 类别,在里面新增 2 个方法,内容只是随机的回传整数和布林值。

class ShoppingCart {
    // ...

    fun dummyInt(): Int {
        return Random.nextInt()
    }

    fun dummyBoolean(): Boolean {
        return Random.nextBoolean()
    }
}

再打开 ShoppingCartTest 类别,执行测试并产生覆盖率报告後,我们可以看到 IntelliJ IDEA 的 Coverage 面板显示的 Method 百分比从原本的 100% 降到 66%、Line 百分比从原本的 100% 降到 71%。

设定 Build Configuration 的 Failure Condition

接着回到 TeamCity,打开专案的 Build Configuration,切到左边侧边栏的 Failure Conditions 设定。我们可以看到 TeamCity 已经内建了数个自动开启的 Failure Condition,比方说当其中一个 Build Step 发生错误(one of build steps exited with an error)、有任一个测试失败(at least one test failed)或是当建置因为记忆体过载而当掉时(an out-of-memory or crash is detected)就会直接视为建置失败。

而我们今天要练习的,是设定 TeamCity 当「Method 覆盖率低於上一次成功建置的数值」时就视为建置失败。点击画面下方 Add failure condition 按钮新增一个条件,出现类型选单时,选择 Fail build on metric change。

接着设定条件,首先设定观测指标是 Method 覆盖率百分比(percentage of method coverage),要比较的对象是上一次成功建置的数值(compared to, value from, Latest successful build),差异不可低於 1%(is less by at least 1 percent),完成後按 Save 储存。

测试 Failure Condition 行为

在 IntelliJ IDEA 完成 Commit & Push 後回到 TeamCity 看建置结果,从 Build 详细页面我们可以看到,虽然建置是有成功且测试也都通过,但因为 Method 覆盖率低於上一次的 100%,所以建置工作也被认定为失败。

小结

经过今天的介绍,相信大家对如何将测试覆盖率应用在 CI 流程有更实际的应用案例,也更清楚如何将覆盖率数值的变化趋势用在 TeamCity 的建置流程中,协助团队更有效率的掌握程序码库品质变化,让维护工作可以更轻松。明天我们将开始探索 CI 在产生 API 文件上的应用,敬请期待!

参考资料


<<:  [Day28]C# 鸡础观念- 物件导向(oop)~ 继承(Inheritance)

>>:  DAY17-MERN

Day30 :【TypeScript 不用学了】我终於完赛了!

终於完赛了!最近跑去画画,附上一幅《小王子与小狐狸》,小王子里面,最喜欢的就是他们的故事,是说画画...

Day 11 - 用Kotlin解数学题:考拉兹猜想

Day 11 - 用Kotlin解数学题:考拉兹猜想 今天我们会用我前面所教的,来解今天的数学题,顺...

Angular ng-container 与 ng-template

接续昨天的范例。 今天要聊的是 ng-container 与 ng-template <ng-...

LeetCode 581. Shortest Unsorted Continuous Subarray

题目 Given an integer array nums, you need to find o...

Day 8:506. Relative Ranks

今日题目 题目连结:506. Relative Ranks 题目主题:Array, Sorting,...