cyz393

Karma简介

Karma是由Google团队开发的前端测试框架,主要的功能:
  1. 启动一个web服务器,生成包含js源代码和js测试脚本的页面;
  2. 运行浏览器加载页面,并显示测试结果;
  3. 如果开启检测,当文件有修改时,立即执行以上过程。

Karma的安装

安装Karma之前要安装Node.js:
    1. 在windows和Ubuntu和Centos上安装Node.js:http://www.runoob.com/nodejs/nodejs-install-setup.html
    2. mac上安装Node.js:
  • brew install node 

安装Karma环境:
  1. 全局安装karma-cli:
    • npm i -g karma-clin  

  2. 在待测项目中安装karma包:
    • npm i --save-dev karma

  3. 因为使用的测试框架是jasmine,还需要在待测项目中安装jasmine:
    • npm install jasmine-core --save-dev

Karma初始化:运行karma init进行测试环境初始化,并按照提示一步步完成:

➜  karma karma init

Which testing framework do you want to use ?

Press tab to list possible options. Enter to move to the next question.

> jasmine

Do you want to use Require.js ?

This will add Require.js plugin.

Press tab to list possible options. Enter to move to the next question.

> no

Do you want to capture any browsers automatically ?

Press tab to list possible options. Enter empty string to move to the next question.

> Chrome

What is the location of your source and test files ?

You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".

Enter empty string to move to the next question.

> src/*.js

> test/*.js

Should any of the files included by the previous patterns be excluded ?

You can use glob patterns, eg. "**/*.swp".

Enter empty string to move to the next question.

Do you want Karma to watch all the files and run the tests on change ?

Press tab to list possible options.

> yes

Config file generated at "/Users/janehai/Documents/karma/karma.conf.js".

 
配置完后,在项目中生成一个karma.conf.js文件,环境搭建完毕。

项目结构

karma-example
    ├── src
         ├── index.js
    ├── test
  	 ├── test.js

示例

index.js的内容:
[javascript] view plain copy
 
  1. function isNum(num) {  
  2.   if (typeof num === \'number\') {  
  3.     return true  
  4.   } else {  
  5.     return false  
  6.   }  
  7. }  
我们使用jasmine测试框架,具体api参考jasmine api,test.js中的内容:
[javascript] view plain copy
 
  1. describe(\'index.js: \', function() {  
  2.   it(\'isNum() should work fine.\', function() {  
  3.     expect(isNum(1)).toBe(true)  
  4.     expect(isNum(\'1\')).toBe(false)  
  5.   })  
  6. })  
 
在项目根目录下运行karma start命令,可以看到下面的运行结果:

➜  karma karma start                        

29 12 2016 11:38:15.620:WARN [karma]: No captured browser, open http://localhost:9876/

29 12 2016 11:38:15.634:INFO [karma]: Karma v1.3.0 server started at http://localhost:9876/

29 12 2016 11:38:15.635:INFO [launcher]: Launching browser Chrome with unlimited concurrency

29 12 2016 11:38:15.651:INFO [launcher]: Starting browser Chrome

29 12 2016 11:38:16.648:INFO [Chrome 55.0.2883 (Mac OS X 10.12.1)]:Connected on socket /#Kc8j_hOrgXwvl7afAAAA with id 26739205

Chrome 55.0.2883 (Mac OS X 10.12.1): Executed 1 of 1 SUCCESS (0.005 secs / 0.001 secs)

运行结果为SUCCESS。
因为之前设置了监控文件的修改,所以每次修改源文件或者测试脚本,Karma都会自动再次运行。

覆盖率

安装karma覆盖率工具:

npm i --save-dev karma-coverage

 
修改karma.conf.js配置文件:
module.exports = function(config) {
  config.set({
    basePath: \'\',
    frameworks: [\'jasmine\'],
    files: [
      \'src/*.js\',
      \'test/*.js\'
    ],
    exclude: [],

    // modified
    preprocessors: {
        \'src/*.js\': [\'coverage\']
    },

    //modified
    reporters: [\'progress\', \'coverage\'],

    // add
    coverageReporter: {
      type : \'html\',
      dir : \'coverage/\'
    },

    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: [\'Chrome\'],
    singleRun: false,
    concurrency: Infinity
  })
}

再运行karma start,在目录下生成coverage目录,里面有本次测试的覆盖报告,如下:

 
 

使用Webpack+Babel

在实际项目中,有事会需要用到Webpack和ES6,所以接下来将Webpack和Babel集成进Karma环境中。

安装karma-webpack

npm i --save-dev karma-webpack

安装babel

npm i --save-dev babel-loader babel-core babel-preset-es2015

然后文件进行改造,src/index.js文件修改为

function isNum(num) {
  if (typeof num === \'number\') {
    return true
  } else {
    return false
  }
}

exports.isNum = isNum

text/index.js文件修改为

const Util = require(\'../src/index\')

describe(\'index.js: \', () => {
  it(\'isNum() should work fine.\', () => {
    expect(Util.isNum(1)).toBe(true)
    expect(Util.isNum(\'1\')).toBe(false)
  })
})

接下来修改配置文件karma.conf.js

module.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\']
          }
        }]
      }
    }
  })
}

注意这里的修改:

  1. files只留下test文件。因为webpack会自动把需要的其它文件都打包进来,所以只需要留下入口文件。

  2. preprocessors也修改为test文件,并加入webpack域处理器

  3. 加入webpack配置选项。可以自己定制配置项,但是不需要entry和output。这里加上babel-loader来编译ES6代码

运行karma start,成功了~

再看看Coverage,卧槽。。居然不是百分之百了。。。

原因很简单,webpack会加入一些代码,影响了代码的Coverage。如果我们引入了一些其它的库,比如jquery之类的,将源代码和库代码打包在一起后,覆盖率会更难看。。这样的Coverage就没有了参考的价值。

还好有大神给我们提供了解决方案,需要安装插件

npm i --save-dev babel-plugin-istanbul

修改webpack中babel-loader的配置

{
  test: /\.js$/,
  loader: \'babel\',
  exclude: /node_modules/,
  query: {
    presets: [\'es2015\'],
    plugins: [\'istanbul\']
  }
}

因为这里引入了istanbul插件来检测Coverage,所以要把preprocessors里的coverage去掉。

搞定以后,运行karma start。当当当当~一切OK啦,尽情编写测试脚本把~

最后附上示例项目地址:karma-example

分类:

技术点:

相关文章: