karma

http://blog.fens.me/nodejs-karma-jasmine/

##前言

Nodejs领域: Jasmine做单元测试,Karma自动化完成单元测试,Grunt启动Karma统一项目管理,Yeoman最后封装成一个项目原型模板,npm做nodejs的包依赖管理,bower做javascript的包依赖管理。Java领域:JUnit做单元测试, Maven自动化单元测试,统一项目管理,构建项目原型模板,包依赖管理。

本文介绍Jasmine+Karma自动化单元测试。

##Karma的介绍

Karma是Testacular的新名字,在2012年google开源了Testacular,2013年Testacular改名为Karma。Karma是一个让人感到非常神秘的名字,表示佛教中的缘分,因果报应,比Cassandra这种名字更让人猜不透!

Karma是一个基于Node.js的JavaScript测试执行过程管理工具(Test Runner)。该工具可用于测试所有主流Web浏览器,也可集成到CI(Continuous integration)工具,也可和其他代码编辑器一起使用。这个测试工具的一个强大特性就是,它可以监控(Watch)文件的变化,然后自行执行,通过console.log显示测试结果。

Jasmine是单元测试框架,本单将介绍用Karma让Jasmine测试自动化完成。Jasmine的介绍,请参考文章:jasmine行为驱动,测试先行

istanbul是一个单元测试代码覆盖率检查工具,可以很直观地告诉我们,单元测试对代码的控制程度。

##Karma的安装

npm install karma --save-dev

# Install plugins that your project needs:
$ npm install karma-jasmine karma-chrome-launcher --save-dev

注意:该语句表示安装到当前目录下面

当你为你的模块安装一个依赖模块时,正常情况下你得先安装他们(在模块根目录下npm install module-name),然后连同版本号手动将他们添加到模块配置文件package.json中的依赖里(dependencies)。

-save和save-dev可以省掉你手动修改package.json文件的步骤。
npm install module-name -save 自动把模块和版本号添加到dependencies部分
npm install module-name -save-dve 自动把模块和版本号添加到devdependencies部分

启动karma,测试是否安装成功

./node_modules/karma/bin/karma start

除此之外我们还需要全局的karma-cli

安装方法

sudo npm install -g karma-cli

##Karma + Jasmine配置

初始化karma配置文件

karma init my.conf.js

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 a browser automatically ?
Press tab to list possible options. Enter empty string to move to the next question.
> Chrome
> Firefox
>

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.
> *.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

##启动 Karma

karma start my.conf.js

##自动化单元测试

3步准备工作:

  1. 创建源文件:用于实现某种业务逻辑的文件,就是我们平时写的js脚本
  2. 创建测试文件:符合jasmineAPI的测试js脚本
  3. 修改karma.conf.js配置文件

###创建源文件:用于实现某种业务逻辑的文件,就是我们平时写的js脚本
有一个需求,要实现单词倒写的功能。如:”ABCD” ==> “DCBA”

~ vi src.js

function reverse(name){
    return name.split("").reverse().join("");
}

###创建测试文件:符合jasmineAPI的测试js脚本

describe("A suite of basic functions", function() {
    it("reverse word",function(){
        expect("DCBA").toEqual(reverse("ABCD"));
    });
});

###修改karma.conf.js配置文件
我们这里需要修改:files和exclude变量

module.exports = function (config) {
    config.set({
        basePath: '',
        frameworks: ['jasmine'],
        files: ['*.js'],
        exclude: ['karma.conf.js'],
        reporters: ['progress'],
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: true,
        browsers: ['Chrome'],
        singleRun: false
    });
};

启动karma

单元测试全自动执行

$ karma start my.conf.js

INFO [karma]: Karma v0.12.31 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
INFO [Chrome 42.0.2311 (Mac OS X 10.10.2)]: Connected on socket HqiWljeM3m-UjEpQuk37 with id 17873649
Chrome 42.0.2311 (Mac OS X 10.10.2): Executed 1 of 1 SUCCESS (0 secs / 0.003 secChrome 42.0.2311 (Mac OS X 10.10.2): Executed 1 of 1 SUCCESS (0.015 secs / 0.003 secs)

浏览器会自动打开

我们修改test.js

~ vi test.js

describe("A suite of basic functions", function() {
    it("reverse word",function(){
        expect("DCBA").toEqual(reverse("ABCD"));
        expect("Conan").toEqual(reverse("nano"));
    });
});

由于karma.conf.js配置文件中autoWatch: true, 所以test.js文件保存后,会自动执行单元测试。

执行日志如下:提示我们单元测试出错了。

INFO [watcher]: Changed file "D:/workspace/javascript/karma/test.js".
Chrome 28.0.1500 (Windows 7) A suite of basic functions reverse word FAILED
        Expected 'Conan' to equal 'onan'.
        Error: Expected 'Conan' to equal 'onan'.
            at null. (D:/workspace/javascript/karma/test.js:4:25)
Chrome 28.0.1500 (Windows 7): Executed 1 of 1 (1 FAILED) ERROR (0.3 secs / 0.006 secs)

##Karma和istanbul代码覆盖率

增加代码覆盖率检查和报告,增加istanbul依赖

$ npm install karma-coverage --save-dev

修改karma.conf.js配置文件

$ vi karma.conf.js

reporters: ['progress','coverage'],
preprocessors : {'src.js': 'coverage'},
}

启动karma start,在工程目录下面找到index.html文件,coverage/chrome/index.html

打开后,我们看到代码测试覆盖绿报告

覆盖率是100%,说明我们完整了测试了src.js的功能。

接下来,我们修改src.js,增加一个if分支

function reverse(name){
    if(name=='AAA') return "BBB";
    return name.split("").reverse().join("");
}

再看覆盖率报告,

Statements:75%覆盖,Branches:50%覆盖。

为了产品的质量我们要尽量达到更多的覆盖率,一般对于JAVA项目来说,能达到80%就是相当高的标准了。对于Javascript的代码测试及覆盖率研究,我还要做更多的验证。

还有不明白的可以去我的github,下载完整版参考
https://github.com/zhanfang/karma_test

详情请参考 https://karma-runner.github.io/0.12/