瘦人说

迟到的Mr.Coverage

Mr.Coverage在一个月以前就有一个alpha版本了,一直没有时间发上来,这两天又抽时间小小更新了下,将就发到blog中记录下,顺便也说说我对Testing慢慢理解的过程。

先说说JavaScriptTesting那些事吧。头两年开发的项目中别说是Testing覆盖率,Testing都很少写,单元Testing几乎没有,对于自动化E2ETesting,之后那个项目才有一些,小项目大部分功能还得专职的Testing人员来Testing。试想一下,在一个不重视前端开发的公司里面,后端代码Testing都很少写,那更不用说前端JavaScript代码的单元Testing,partial页面Testing等等了。那个时候Testing覆盖率神马的都是浮云。

之后我接触到了QUnit,不知道啥时候发布的,感觉挺好,断言方式也比较亲切,我便给我自己写的几个小东西加上了单元Testing,包括Mr.Async,Mr.Array这些无人问津的练习项目,感觉Testing的还挺全乎的,也渐渐对加Testing(注意是用的加)产生了好感。那时候也没人教Testing应该是什么样子的,现在回头看看,mock、stub、spy等技术完全没有涉及到。。。,这也侧面说明我那些Library微不足道。

TW是非常重视Testing的公司,Testing的重要性我不必说了。在这里的项目中让我了解到了Testing应该怎么做,我其实花了一些时间去让我的笨脑子去学习stub、spy、mock等等,尤其是前端开发的Testing。其中很有趣的是Testing覆盖率这个像是指标一样的东西,每提高一个百分点都会足以让人欣喜。ruby代码的Testing已经是100%了,没什么刺激点了,但是我发现JS的覆盖率才是可怜的30%(我刚到的时候),这意味这作为一个UI开发来说,应该focus到这些地方。澳洲那边有位之前做JS开发的QA,这半年的前几个月都是他一直在抓JS的Testing和重构,可谓呕心沥血,在他的带领下,覆盖率上升到了40+%。10多个百分点的提升已经非常让人兴奋不已,再说人都是喜欢干能让自己开心的事,那时我想一定在离开之前把覆盖率提升到70%。如果回头看看旁边的报表组的JS覆盖率,那是相当可怕的90%啊,更有使用Backbone的项目Testing率100%。

提高JS覆盖率不是找一堆代码运行下就ok的,Testing需要有代码的可Testing性,也就是是否有划分模块。现在前端模块开发变得非常重要,模块化开发不单是面对Testing,在可维护性上都会有很大提升。我们项目在重写和重构之前这点做得确实不好,慢慢把老代码使用OO方式重写,然后加上Testing,覆盖率才有所上升的。现在的Testing覆盖率是61%吧,也是处于渐渐变更的状态。

在提升覆盖率的同时也会研究下原理是什么。项目TestingJS是用jasmine,Testing覆盖率是用的整合到rails项目中的一个工具,没深度研究过,但发现实质上运行JS代码的还是需要jasmine配合,当然选用其他也可以。后来由于深度学习node,接触到了mocha,发现mocha比jasmine好用不止一点点,而且mocha中各种报表格式的显示也非常精致和有趣。这也是为什么Mr.Coverage第一个版本中使用了jasmine,后来被替换为mocha的主要原因。

原理

貌似所有Testing覆盖率的原理都大同小异,都是把源码利用工具生成为同等功能的目标代码,目标代码中含有每行执行次数的变量,当代码运行时刻,某一行被执行时,相对应的变量就会++,运行完成时,通过对这些变量的统计得出覆盖率。行覆盖率应该是这个原理。JS的目标代码生成工具是10年已经没有在更新的jscoverage,虽然没有在更新,但是几乎所有的JS覆盖率Testing都需要用到这个工具,它的牛X程度可见一斑。无例外,Mr.Coverage里面也整合了jscoverage这个工具,不过是github上的一个针对node的变体,叫做node-jscoverage,不过使用起来毫无它的存在感。

使用它可以对代码进行这样的处理:

var _ = require('underscore');
 
_.extend(exports, {
	add : function(a, b) {
		return a + b;
	},
	minus : function(a, b) {
		return a - b;
	},
	multiply : function(a, b) {
		return a * b;
	},
	divide : function(a, b) {
		return a / b;
	},
	increment : function(a) {
		return a++;
	}
});

会被编译成含有一个_$jscoverage对象的代码,但其功能保持不变:

if (typeof _$jscoverage === 'undefined') _$jscoverage = {};
if (! _$jscoverage['script.js']) {
  _$jscoverage['script.js'] = [];
  _$jscoverage['script.js'][1] = 0;
  _$jscoverage['script.js'][3] = 0;
  _$jscoverage['script.js'][5] = 0;
  _$jscoverage['script.js'][8] = 0;
  _$jscoverage['script.js'][11] = 0;
  _$jscoverage['script.js'][14] = 0;
  _$jscoverage['script.js'][17] = 0;
}
_$jscoverage['script.js'][1]++;
var _ = require("underscore");
_$jscoverage['script.js'][3]++;
_.extend(exports, {add: (function (a, b) {
  _$jscoverage['script.js'][5]++;
  return a + b;
}), minus: (function (a, b) {
  _$jscoverage['script.js'][8]++;
  return a - b;
}), multiply: (function (a, b) {
  _$jscoverage['script.js'][11]++;
  return a * b;
}), divide: (function (a, b) {
  _$jscoverage['script.js'][14]++;
  return a / b;
}), increment: (function (a) {
  _$jscoverage['script.js'][17]++;
  return a++;
})});
_$jscoverage['script.js'].source = ["var _ = require('underscore');","","_.extend(exports, {","\tadd : function(a, b) {","\t\treturn a + b;","\t}, ","\tminus : function(a, b) {","\t\treturn a - b;","\t}, ","\tmultiply : function(a, b) {","\t\treturn a * b;","\t}, ","\tdivide : function(a, b) {","\t\treturn a / b;","\t}, ","\tincrement : function(a) {","\t\treturn a++;","\t}","});"];

代码运行之后可以通过分析全局变量_$jscoverage,计算出Testing覆盖率。

Mr.Coverage

使用Mr.Coverage是需要NodeJS环境的,所以在使用前还是去github看看如何安装先,4步搞定安装。Mr.Coverage的目的是整合JSTesting框架(mocha)和jscoverage工具,在TestingJS的同时也可以Testingcoverage是多少,不需要开发人员去开发如何混合使用而浪费时间。Mr.Coverage完美支持mocha的所有功能,也就是说mocha能跑的Testing,它一样能跑,并且还支持多个文件夹和多个文件路径作为参数进行Testing,算是点小增强吧。同时,原生mocha不支持的html-cov和json-cov两种report格式也在Mr.Coverage中支持,使用它可以直接设置mocha的报表类型为html-cov,直接导出Testing覆盖率的html代码,相当之爽快。BTW,html-cov到处的页面还是比较漂亮的。有兴趣的可以查看这个report页面

有了这个小工具,肯定是希望有更多人使用,在github上有5个人watch(包括我自己)感觉都很爽,希望会有更多。现在只是完成了小部分功能,要让更多人使用,肯定是需要和成熟的开发框架结合,能配置到自动化Testing中才是王道。另外,很没有写过console程序,提示信息的友好度有待提升,Testing文件的可配置型需要加强等等。

昨天看到一个04年的帖子,里面讲到了04年时候有个比较火的jsvm的东西,评论很精彩,看评论的时候发现,国内那时对于前端开发已经了解得非常深了,当时人早已经把JS模块化开发,后端的JS等等现在我们都还很热门的问题了解的很透彻了,自愧不如啊。总结下就是,我能想到的,人家早已想到,我能做到的,人家已经做了无数的尝试。在一鸣惊人的创造力之前,更重要的是自己的执行力,成功并不是有了想法就可以的,它还需要长时间的平凡的坚持。(不知道为什么说到这个⋯⋯)

今天听到老邢讲Design Thinking,我猛然发现自己是他讲到的那种经常问how而非why的人。写的blog也是关于如何做事的内容较多。不是对号入座吧,如果想朝UX方面发展,凡是还得多问问为什么。

希望Mr.Coverage能带给你lots of fun。

Comments

Proudly published with Hexo