前言在前端开发中,测试往往是一个被忽视的环节。因此,最近一直在研究前端自动化测试框架Karma,把个人的学习过程分享出来,希望对大家有所帮助。什么是业力?Karma是Google团队开发的前端测试运行框架。它不同于测试框架(如jasmine、mocha等),运行在这些测试框架之上。主要完成工作:Karma启动一个web服务器,生成一个包含js源代码和js测试脚本的页面;运行浏览器加载页面,并显示测试结果;如果启用检测,当文件被修改时,执行继续执行上述过程。Karma的安装配置初始项目结构karma-example├──src├──index.js├──test├──package.jsonindex.js内容如下functionisNum(num){if(typeofnum==='number'){returntrue}else{returnfalse}}安装Karma环境为了方便搭建Karma环境,我们可以全局安装karma-cli来帮助我们初始化测试环境:npmi-gkarma-cli然后安装karma包项目中的npmi--save-devkarma运行项目目录下的karmainit初始化测试环境,按照提示一步步执行。上图为选项示例,这里我们使用jasmine测试框架,PhantomJS作为代码运行环境(也可以选择其他浏览器作为运行环境,如Chrome、IE等)。***在项目中生成karma.conf.js文件。至此,基本的Karma运行环境已经搭建完成。运行Karma以在测试目录中编写一个简单的测试脚本。我们使用茉莉花测试框架。具体的api请参考jasmineapi。内容如下describe('index.js:',function(){it('isNum()shouldworkfine.',function(){expect(isNum(1)).toBe(true)expect(isNum('1')).toBe(false)})})然后在项目根目录运行karmastart命令,我们可以看到运行结果如下,运行结果表明测试成功.同时,由于我们之前设置了监控文件修改,当我们修改源文件或测试脚本时,Karma会自动为我们再次运行,无需手动操作。Coverage如何衡量测试脚本的质量?其中一个参考指标是代码覆盖率(coverage)。什么是代码覆盖率?简而言之,就是测试中运行的代码占全部代码的比例。其中又可分为线号覆盖、分支覆盖等。具体含义就不细说了,有兴趣的可以自行查阅资料。虽然并不是说代码覆盖率越高,测试脚本就写得越好(见参考资料4),但是代码覆盖率对于编写测试脚本还是有一定的指导意义的。所以接下来我们将Coverage添加到Karma环境中。先安装Karma覆盖工具npmi--save-devkarma-coverage然后修改配置文件karma.conf.js,module.exports=function(config){config.set({basePath:'',frameworks:['jasmine'],files:['src/**/*.js','test/**/*.js'],exclude:[],//modifiedpreprocessors:{'src/**/*.js':['coverage']},//modifiedreporters:['progress','coverage'],//addcoverageReporter:{type:'html',dir:'coverage/'},port:9876,colors:true,logLevel:config.LOG_INFO,autoWatch:true,browsers:['PhantomJS'],singleRun:false,concurrency:Infinity})}再次运行karmastart后,该目录下会生成一个覆盖目录,里面有本次测试的覆盖报告.打开后的结果如下UsingWebpack+Babel在实际项目中,有时需要用到Webpack和ES6,所以下一步就是将Webpack和Babel集成到Karma环境中。安装karma-webpacknpmi--save-devkarma-webpackinstallbabelnpmi--save-devbabel-loaderbabel-corebabel-preset-es2015然后修改文件,修改src/index.js文件为functionisNum(num){if(typeofnum==='number'){returntrue}else{returnfalse}}exports.isNum=isNumtext/index.js文件修改为constUtil=require('../src/index')describe('index.js:',()=>{it('isNum()应该工作正常。',()=>{expect(Util.isNum(1)).toBe(true)expect(Util.isNum('1')).toBe(false)})})接下来修改配置文件karma.conf.jsmodule.exports=function(config){config.set({basePath:'',frameworks:['jasmine'],files:['test/**/*.js'],exclude:[],preprocessors:{'test/**/*.js':['webpack','coverage']},reporters:['progress','coverage'],coverageReporter:{type:'html',dir:'coverage/'},port:9876,colors:true,logLevel:config.LOG_INFO,autoWatch:true,browsers:['PhantomJS'],singleRun:false,concurrency:Infinity,webpack:{module:{loaders:[{test:/\.js$/,loader:'babel',exclude:/node_modules/,query:{presets:['es2015']}}]}}})}注意这里的修改:filesonly保留测试文件。因为webpack会自动打包所有其他需要的文件,所以只需要留下入口文件。预处理器也被修改为测试文件,并添加webpack域处理器以添加webpack配置选项。您可以自己自定义配置项,但不需要录入和输出。在这里添加babel-loader编译ES6代码,运行karmastart,成功~再来看看Coverage,妈的。.已经不是***了。..原因很简单,webpack会增加一些代码,影响代码的覆盖率。如果再引入一些其他的库,比如jquery,将源代码和库代码打包在一起后,覆盖面就更丑了。.这样的Coverage没有参考价值。幸好有大神给我们提供了解决方案。我们需要安装插件npmi--save-devbabel-plugin-istanbul来修改webpack中babel-loader的配置{test:/\.js$/,loader:'babel',exclude:/node_modules/,query:{presets:['es2015'],plugins:['istanbul']}}因为这里引入了istanbul插件来检测Coverage,所以预处理器中的coverage应该去掉。完成后,运行karmastart。当当当当~一切OK,想写多少测试脚本就写多少~***附上示例项目地址:karma-example
