在测试时,我们的用例把所有代码都覆盖了吗? 对于这个问题引出了代码覆盖率的测试指标,一共有以下4种:
istanbul 是一个代码覆盖工具
它可以帮助我们检查代码的覆盖率
在一个项目中,可以通过 istanbul 设定某些覆盖率阈值来保证测试用例的齐全完整程度,用来保证代码质量
下面是对 istanbul 的使用&学习所得
需要安装 mocha,should,istanbul
$ npm install mocha $ npm install should $ npm install istanbul
mocha 是测试框架,should 是断言库
先来看看我们的测试文件:
// index.js function add(a, b) { a = a || 0; b = b || 0; return a + b; } add(1, 2);
很简单的一个两位数相加的函数,好,我们执行命令:
$ ./node_modules/.bin/istanbul cover index.js
得出下面的结果:
============ Coverage summary ============ Statements : 100% ( 5/5 ) Branches : 50% ( 2/4 ) Functions : 100% ( 1/1 ) Lines : 100% ( 5/5 ) ==========================================
可以看到,列出了4个覆盖率指标的结果
结果表示,语句,代码行还有函数都是100%执行了,但是并不是所有分支都执行过了
那么具体哪些分支没有被执行?
我们可以通过自己肉眼去查看,并且通过大脑去“执行”代码,这是笨方法
istanbul 给我们提供了一个直观的查看结果的方式: 网页版结果报告
在执行了命令之后,在当前目录你会发现新生成了一个文件夹: coverage
这个文件夹下面包含了代码覆盖率结果文件以及代码覆盖率结果报告
直接打开 coverage/lcov-report/index.html
,会在浏览器看到以下页面:
这个页面通过一个很直观的方式来展示每个文件夹下面的文件的代码覆盖率
点击文件夹,可以看到每个具体的文件的代码覆盖率情况:
点击文件名,我们就可以看到该文件的源代码,以及一些代码未有覆盖的情况:
可以看到上面有两个地方标了黄色,也就是说代码没有执行到那些地方
!
, &&
, ||
, ?:
if
和 else
switch - case
还是刚刚的例子,这次我们改一下:
// index.js function add(a, b) { a = a || 0; b = b || 0; return a + b; } module.exports = add;
这样,我们就得到了一个非自启动的模块
那么,我们需要编写单元测试:
var should = require('should'); var add = require('./index'); describe('add', () => { it('1 + 2', () => { add(1, 2).should.be.equal(3); }); });
然后我们执行命令:
$ ./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha -- test.js
结果如下:
============ Coverage summary ============ Statements : 100% ( 10/10 ) Branches : 50% ( 2/4 ) Functions : 100% ( 1/1 ) Lines : 100% ( 10/10 ) ==========================================
注意:这里结果和之前不一样是因为这里还统计了测试用例自身的代码覆盖率情况
这是在 windows 系统,所以需要用 ./node_modules/mocha/bin/
下面的 mocha
mocha
前面加的下划线是不能省略的
因为, mocha
和 _mocha
是两个不同的命令,前者会新建一个进程执行测试,而后者是在当前进程(即 istanbul 所在的进程)执行测试,只有这样, istanbul
才会捕捉到覆盖率数据。其他测试框架也是如此,必须在同一个进程执行测试
--
后面的部分,都会被当作参数传入 mocha
。如果不加,它们就会被当作 istanbul
的参数
执行下面命令:
$ ./node_modules/.bin/istanbul check-coverage --statement 90 --branch 90 --function 90
这行命令的意思是检查代码覆盖率结果是否超过阈值指标,这里设置了指标是:语句覆盖率要超过 90%,分支覆盖率要超过 90%,函数覆盖率要超过 90%
结果如下:
ERROR: Coverage for branches (50%) does not meet global threshold (90%)
结果提示说分支覆盖率没有打到指标。。。
通过查看代码覆盖率结果报告,知道我们忽略了哪些分支情况后,我们就要需要添加新的测试用例去覆盖这些情况:
var should = require('should'); var add = require('./index'); describe('add', () => { it('1 + 2', () => { add(1, 2).should.be.equal(3); }); it('1 + undefined', () => { add(1).should.be.equal(1); }); it('undefined + 2', () => { add(undefined, 2).should.be.equal(2); }); });
这次我们再执行代码覆盖率检查命令:
$ ./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha -- test.js
会得到这样的结果:
============ Coverage summary ============ Statements : 100% ( 14/14 ) Branches : 100% ( 4/4 ) Functions : 100% ( 1/1 ) Lines : 100% ( 14/14 ) ==========================================
这一次,我们再执行代码覆盖率阈值检测命令:
$ ./node_modules/.bin/istanbul check-coverage --statement 90 --branch 90 --function 90
就不会有报错信息了
在真实项目中,代码覆盖率工具可以帮助我们 完善测试用例 ,保证 代码及项目的质量
通常在测试自动化的基础上,我们再加上代码覆盖率的自动化阈值检测,用来保证测试用例的完整性