Open hwen opened 7 years ago
原文发于我的博客:https://github.com/hwen/blogSome/issues/1
写在前面:本文主要介绍一下前端单元测试,并提供一个单元测试的例子(模板),主要是例子为主,通过尝试就能慢慢上手前端单元测试。并记录自己的一些单元测试调试技巧。
关于这个 cnode 上就有个很有意思的讨论
做个调查,你的 Node 应用有写单测吗?
看完这个应该会有结论?如果没有,就回帖跟别人探讨下~
测试有分为
主要区别是单测倾向于测试模块内部运行逻辑及功能,集成测试倾向于模块间互相组合跟调用的测试。 系统测试(当然你要说,还有自动化测试)是对整个系统的测试,主要由测试人员而非开发人员负责。
本文只讨论单测的范畴,对集成测试有兴趣的话,可以看下 Vue 的集成测试代码。
测试本质上就是假定一个输入,然后判断得到预期的输出。而前端与后端相比,夹杂着浏览器 DOM 操作,异步请求, 浏览器兼容性等方面的。要我来说,比后端写单测要麻烦多了。。。
不过现在前端的单测已经发展得比较完善了,已经有一套比较完整的工具链,来完成各种需求。
目前比较流行的测试框架有:
用得比较多的就上面两个,还有一些用得比较少的,比如 Qunit、intern
框架的实现原理其实就是检测内部运行的代码是否有抛出异常。而断言库如果没有得到预期的输入时,就会抛出异常,给框架检测到。
PS.想要学 mocha 和单测写法,最好的资源就是 express 框架的测试代码(狼叔推荐,亲测很不错)
spies
stub
fake XMLHttpRequest
Fake server
Fake time
(并不是学会,就是这么耿直 (:з)∠),手是谁???)
使用的是:karma + mocha + chai + sinon(如果之前没了解过这几个,可以边写边看文档,这样学会快很多)
完整的例子可以在这里找到:GitHub 项目 建议把项目 clone 下来自己跑一遍,然后可以自己加一些特效(啊,不对,是代码才对。。。
详细代码,及配置见 源码
it('test dom', () => { const div = document.getElementById('test') const content = div.innerHTML content.should.be.equal('here') setDivContent() const after = div.innerHTML after.should.be.equal('hallo world') })
it('test async', done => { getTopics() .then(res => { res.success.should.be.equal(true) done() }) .catch(err => { info(err) done(err) }) })
当你的单元测试越写越多时,想测试新写的单测是否正确时,可以用 mocha 的 only 这样做的好处有二:第一屏蔽其他测试可以使测试速度变得更快,第二屏蔽其他测试,可以在你新写的测试错误时 确定这个错误不是被其他测试所影响导致的。
用法
describe.only('something', function() { // 只会跑包在里面的测试 })
或者
it.only('do do', () => { // 只会跑这一个测试 })
要开启 debug 的话,先在 karma.conf.js 把 singleRun 改成 false 然后,看图(懒得打字了 (:з)∠)
karma.conf.js
singleRun
false
生成覆盖率报告也是相当简单,不过有个要注意的地方就是 现在前端代码很多都是经过 webpack,babel 编译的,生成的代码会多了很多二外的代码
webpack
babel
要解决这个问题使用babel-plugin-istanbul来替代karma-coverage就可以了
babel-plugin-istanbul
karma-coverage
preprocessors: { 'src/**/*.js': ['webpack', 'coverage'], 'test/*.test.js': ['webpack'] }
将 karma-coverage 去掉,变成
preprocessors: { 'src/**/*.js': ['webpack'], 'test/*.test.js': ['webpack'] }
然后在 webpack 配置添加 istanbul 插件
use: { loader: 'babel-loader', options: { plugins: ['istanbul'] } }
最后可以生成覆盖率报告
另外有很多工具可以对生成的覆盖率报告进行进一步的分析,比如最常见的 你会在 Github 上经常见到的图标
这个就是利用报告里的lcovonly分析生成的
lcovonly
coverageReporter: { dir: 'test/coverage/', reporters: [ { type: 'html', subdir: 'report-html' }, { type: 'lcovonly', subdir: '.', file: 'report-lcovonly.txt' }, // 这里,你可以重命名 file { type: 'text-summary', subdir: '.', file: 'text-summary.txt' } ] }
karma-cover
前面有说到,为什么不用 should.js?? 因为如果你用 ES6 的语法写单测(webpack 编译),用 import should-sinon 会报错。。 (是不是因为 tj 大神写完东西不喜欢维护的习惯导致should.js支持性不好???)
should.js
原文发于我的博客:https://github.com/hwen/blogSome/issues/1
写在前面:本文主要介绍一下前端单元测试,并提供一个单元测试的例子(模板),主要是例子为主,通过尝试就能慢慢上手前端单元测试。并记录自己的一些单元测试调试技巧。
要不要写单测?
关于这个 cnode 上就有个很有意思的讨论
做个调查,你的 Node 应用有写单测吗?
看完这个应该会有结论?如果没有,就回帖跟别人探讨下~
测试
测试有分为
主要区别是单测倾向于测试模块内部运行逻辑及功能,集成测试倾向于模块间互相组合跟调用的测试。 系统测试(当然你要说,还有自动化测试)是对整个系统的测试,主要由测试人员而非开发人员负责。
本文只讨论单测的范畴,对集成测试有兴趣的话,可以看下 Vue 的集成测试代码。
前端单测现状
测试本质上就是假定一个输入,然后判断得到预期的输出。而前端与后端相比,夹杂着浏览器 DOM 操作,异步请求, 浏览器兼容性等方面的。要我来说,比后端写单测要麻烦多了。。。
不过现在前端的单测已经发展得比较完善了,已经有一套比较完整的工具链,来完成各种需求。
单测工具链
框架
目前比较流行的测试框架有:
用得比较多的就上面两个,还有一些用得比较少的,比如 Qunit、intern
框架的实现原理其实就是检测内部运行的代码是否有抛出异常。而断言库如果没有得到预期的输入时,就会抛出异常,给框架检测到。
PS.想要学 mocha 和单测写法,最好的资源就是 express 框架的测试代码(狼叔推荐,亲测很不错)
断言库
mock 库
spies
,stub
,fake XMLHttpRequest
,Fake server
,Fake time
,很强大测试集成工具
半小时上手单测
(并不是学会,就是这么耿直 (:з)∠),手是谁???)
使用的是:karma + mocha + chai + sinon(如果之前没了解过这几个,可以边写边看文档,这样学会快很多)
完整的例子可以在这里找到:GitHub 项目 建议把项目 clone 下来自己跑一遍,然后可以自己加一些特效(啊,不对,是代码才对。。。
测试 DOM
详细代码,及配置见 源码
测试异步请求
调试技巧
调试技巧之一:善用 only
当你的单元测试越写越多时,想测试新写的单测是否正确时,可以用 mocha 的 only 这样做的好处有二:第一屏蔽其他测试可以使测试速度变得更快,第二屏蔽其他测试,可以在你新写的测试错误时 确定这个错误不是被其他测试所影响导致的。
用法
或者
调试技巧之二:善用 debug
要开启 debug 的话,先在
karma.conf.js
把singleRun
改成false
然后,看图(懒得打字了 (:з)∠)覆盖率
生成覆盖率报告也是相当简单,不过有个要注意的地方就是 现在前端代码很多都是经过
webpack
,babel
编译的,生成的代码会多了很多二外的代码要解决这个问题使用
babel-plugin-istanbul
来替代karma-coverage
就可以了将 karma-coverage 去掉,变成
然后在 webpack 配置添加 istanbul 插件
最后可以生成覆盖率报告
另外有很多工具可以对生成的覆盖率报告进行进一步的分析,比如最常见的 你会在 Github 上经常见到的图标
这个就是利用报告里的
lcovonly
分析生成的一些坑
babel-plugin-istanbul
代替karma-cover
来检测覆盖率补充
前面有说到,为什么不用
should.js
?? 因为如果你用 ES6 的语法写单测(webpack 编译),用 import should-sinon 会报错。。 (是不是因为 tj 大神写完东西不喜欢维护的习惯导致should.js支持性不好???)