title: 100% code coverage != 100% test
date: 2017-02-16 10:32:59
tags:

- QA

100% code coverage != 100% test

引言

avatar

很多人看到这个标题时,就在想你都100%代码覆盖了,怎么还会有问题呢?

让我们看看一下代码栗子:

Code example

1
2
3
4
5
6
7
8
9
public class TestCalculator {
public Double add(Double a, Double b) {
return a + b;}
}

再让我们看看用junit写出的测试代码:

@Test

public void testAdd() {

Double a = new Double(1);

Double b = new Double(2);

Double c = new Double(3);

assertEquals(c, testCalculator.add(a, b));

}
当我们在Eclipse使用 EclEmme Code Coverage 插件测试时, 对于这个类我们将得到 100% Line-Coverage.
avatar

一切看起来都那么的完美,真是这样的吗?

好吧,让我们来来看看另一个测试,当其中一个变量为null时,返回值将会怎样?

1
2
3
4
5
6
7
8
9
10
11
12
13
@Test
public void testAddNullPointerException() {
Double a = new Double(1);
Double b = null;
Double c = new Double(3);
assertEquals(c, testCalculator.add(a, b));
}

好了,你会发现尽管你的覆盖率为100%,但程序却抛出了NullPointerException异常。

对于很多PM来说会选择第一个测试代码,因为100%的单元测试覆盖率总比50%的测试代码要更好!

但是这有用么?我们可能忽略了更重要的业务场景测试。

哈哈,小小的嘲讽了部分PM。

我们应当转换下思维,思考以下问题。

100%的覆盖率并不意味你的测试代码质量很高,上面那个列子就是典型。

100%的覆盖率并不意味着所有的业务场景都被覆盖。

对于项目我们是否有足够的测试?
avatar

这里的测试不仅仅包括代码级别的单元测试,还要集成测试,接口测试,黑盒测试,可用性测试等等。只有全部得测试通过后,才能说明功能的完整性,仅仅单一的单元测试,对于整个项目来说,基本没用。

所以100%的代码覆盖率值得追求吗?
avatar

是的,这应该是每个程序猿毕生追求的之一,但是如果从项目角度考虑,ROI(投入产出比),如果你的项目是一个短期项目,需要快速上线,那么这时候你需要注重的是测试应覆盖核心功能代码。如果你的项目是一个长期项目,那么高覆盖率是非要有必要的,它意味着可维护性,以及更少的bug。(前提是你的测试采用TDD/BDD方式编写,我见过将测试代码写的一团糟的人,看着他的代码,我宁愿重新一遍)

那么对于一个项目来说覆盖率应该达到多少?

其实没有具体数值能够覆盖到所有的项目,每个项目都应有自己的阈值,但共性是,必须测试必须覆盖主要业务场景,代码的逻辑分支也必须覆盖。

如何改进你的项目代码覆盖率?

阅读和理解项目代码,找出其中需要测试并且与业务强相关的代码。

将之前可读性差测试代码,采用TDD与BDD方式进行重写,提高项目的可维护性与可读性。

代码覆盖率非常重要的意义在于:

分析未覆盖部分的代码,从而反推在前期黑盒测试设计是否充分,没有覆盖到的代码是否是测试设计的盲点,为什么没有考虑到?是需求/设计不够清晰,还是测试设计的理解有误。

检测出程序中的废代码,可以逆向反推在代码设计中不合理的地方,提醒设计/开发人员理清代码逻辑关系,提升代码质量。

代码覆盖率高不能说明代码质量高,但是反过来看,代码覆盖率低,代码质量绝对不会高到哪里去,可以作为测试自我审视的重要工具之一。