Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript代码覆盖率工具 Istanbul入门 #100

Open
kvkens opened this issue Aug 7, 2016 · 0 comments
Open

JavaScript代码覆盖率工具 Istanbul入门 #100

kvkens opened this issue Aug 7, 2016 · 0 comments

Comments

@kvkens
Copy link
Member

kvkens commented Aug 7, 2016

代码覆盖率其实我觉得一直离我很远,但是我现在觉得维护的库代码是否所有的都执行过了,早的时候我在cnodejs社区就看到唐少写的跑覆盖率测试,看来这个东西蛮必要的,所以就把学习的经历分享下…… :)

引用阮一峰的一段博客:
"代码覆盖率"(code coverage)。它有四个测量维度分别是:

  • 行覆盖率(line coverage):是否每一行都执行了?
  • 函数覆盖率(function coverage):是否每个函数都调用了?
  • 分支覆盖率(branch coverage):是否每个if代码块都执行了?
  • 语句覆盖率(statement coverage):是否每个语句都执行了?
Istanbul 是 JavaScript 程序的代码覆盖率工具,介绍下它的用法吧。

1、安装

Istanbul 是npm的一个模块,命令如下:

npm install -g istanbul

安装完成后,我们来看看怎么使用

2、覆盖率测试

新建脚本文件test.js

var x = 5;
var y = 7;
if ((x + y) > 12) {
  console.log('大于12');
}

然后使用 istanbul cover 命令,就能得到覆盖率。

执行istanbul cover test.js

D:\Code\FEStudy\istanbul>istanbul cover test.js
=============================================================================
Writing coverage object [D:\Code\FEStudy\istanbul\coverage\coverage.json]
Writing coverage reports at [D:\Code\FEStudy\istanbul\coverage]
=============================================================================

=============================== Coverage summary ==============================

Statements   : 75% ( 3/4 )
Branches     : 50% ( 1/2 )
Functions    : 100% ( 0/0 )
Lines        : 75% ( 3/4 )
===============================================================================

看到结果是酱紫的……

test.js 有4个语句(statement),执行了3个;有2个分支(branch),执行了1个;有0个函数,调用了0个;有4行代码,执行了3行。

同时还在项目根目录生成一个文件夹coverage,打开coverage/lcov-report/index.html

其中的 coverage.json 文件包含覆盖率的原始数据,coverage/lcov-report 是可以在浏览器打开的覆盖率报告,其中有详细信息,到底哪些代码没有覆盖到。

3、覆盖率门槛

完美的覆盖率当然是 100%,但是现实中很难达到。需要有一个门槛,衡量覆盖率是否达标。

istanbul check-coverage 命令用来设置门槛,同时检查当前代码是否达标。

istanbul check-coverage --statement 90

ERROR: Coverage for statements (75%) does not meet global threshold (90%)

上面命令设置语句覆盖率的门槛是 90% ,结果就报错了,因为实际覆盖率只有75%。
除了百分比门槛,我们还可以设置绝对值门槛,比如只允许有一个语句没有被覆盖到。
istanbul check-coverage --statement -1

上面命令使用负数,表示绝对值门槛。这样一来,上面的例子就通过了覆盖率测试,不会再报错了。
百分比门槛和绝对值门槛,可以结合使用。

istanbul check-coverage --statement -5 --branch -3 --function 100

上面命令设置了3个覆盖率门槛:5个语句、3个 if 代码块、100%的函数。注意,这三个门槛是"与"(and)的关系,只要有一个没有达标,就会报错。

4、与测试框架的结合

给大家介绍下与mocha测试框架一起使用

sqrt.js 是一个计算平方根的脚本。

var My = {
  sqrt: function(x) {
    if (x < 0) throw new Error("负值没有平方根");
      return Math.exp(Math.log(x)/2);
    }
};

module.exports = My;

它的测试脚本 test.sqrt.js 放在 test 子目录。

var chai = require('chai');
var expect = chai.expect;
var My = require('../sqrt.js');

describe("sqrt", function() {

  it("4的平方根应该等于2", function() {
    expect(My.sqrt(4)).to.equal(2);
  });

  it("参数为负值时应该报错", function() {
    expect(function(){ My.sqrt(-1); }).to.throw("负值没有平方根");
  });

});

然后,执行下面的命令得到代码覆盖率。

 istanbul cover _mocha
// or
 istanbul cover _mocha test/test.sqrt.js

  sqrt
    ✓ 4的平方根应该等于2 
    ✓ 参数为负值时应该报错 

  2 passing (7ms)

===== Coverage summary =====
Statements   : 100% ( 5/5 )
Branches     : 100% ( 2/2 )
Functions    : 100% ( 1/1 )
Lines        : 100% ( 4/4 )
=============================

上面命令中,istanbul cover 命令后面跟的是 _mocha 命令,前面的下划线是不能省略的。
因为,mocha 和 _mocha 是两个不同的命令,前者会新建一个进程执行测试,而后者是在当前进程(即 istanbul 所在的进程)执行测试,只有这样, istanbul 才会捕捉到覆盖率数据。其他测试框架也是如此,必须在同一个进程执行测试。

(完)

参考文献:Cnodejs.org & 阮一峰博客

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant