Karma和Jasmine自动化单元测试

从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!

关于作者

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/nodejs-karma-jasmine/

karma

前言

在Java领域,Apache, Spring, JBoss 三大社区的开源库,包罗万象,但每个库都在其领域中都鹤立鸡群。而Nodejs中各种各样的开源库,却让人眼花缭乱,不知从何下手。

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

Nodejs让组合变得更丰富,却又在加重我们的学习门槛。我还说不清楚,也看不透!

上面写的有点远了,回到文章的主题,Jasmine+Karma自动化单元测试。

目录

  1. Karma的介绍
  2. Karma的安装
  3. Karma + Jasmine配置
  4. 自动化单元测试
  5. Karma和istanbul代码覆盖率
  6. Karma第一次启动时出现的问题

1. 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是一个单元测试代码覆盖率检查工具,可以很直观地告诉我们,单元测试对代码的控制程度。

2. Karma的安装

系统环境:

win7 64bit, node v0.10.5, npm 1.2.19

安装Karma


~ D:\workspace\javascript>mkdir karma
~ D:\workspace\javascript>cd karma
~ D:\workspace\javascript\karma>npm install -g karma

# 测试是否安装成功
~ D:\workspace\javascript\karma>karma start
INFO [karma]: Karma v0.10.2 server started at http://localhost:9876/
INFO [Chrome 28.0.1500 (Windows 7)]: Connected on socket nIlM1yUy6ELMp5ZTN9Ek

从浏览器看到karam界面。

karma1

下面我们要开始配置karam。

3. Karma + Jasmine配置

初始化karma配置文件karma.conf.js


~ D:\workspace\javascript\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 a browser 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.
>

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 "D:\workspace\javascript\karma\karma.conf.js".

安装集成包karma-jasmine


~ D:\workspace\javascript\karma>npm install karma-jasmine

4. 自动化单元测试

3步准备工作:

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

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


~ vi src.js

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

2). 创建测试文件:符合jasmineAPI的测试js脚本


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

3). 修改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'],
        captureTimeout: 60000,
        singleRun: false
    });
};

启动karma
单元测试全自动执行


~ D:\workspace\javascript\karma>karma start karma.conf.js
INFO [karma]: Karma v0.10.2 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
WARN [launcher]: The path should not be quoted.
  Normalized the path to C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
INFO [Chrome 28.0.1500 (Windows 7)]: Connected on socket bVGffDWpc1c7QNdYye_6
INFO [Chrome 28.0.1500 (Windows 7)]: Connected on socket DtTdVbd4ZsgnMQrgye_7
Chrome 28.0.1500 (Windows 7): Executed 1 of 1 SUCCESS (3.473 secs / 0.431 secs)
Chrome 28.0.1500 (Windows 7): Executed 1 of 1 SUCCESS (0.068 secs / 0.021 secs)
TOTAL: 2 SUCCESS

浏览器会自动打开
karma2

我们修改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)

5. Karma和istanbul代码覆盖率

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


~ D:\workspace\javascript\karma>npm install karma-coverage

修改karma.conf.js配置文件


~ vi karma.conf.js

reporters: ['progress','coverage'],
preprocessors : {'src.js': 'coverage'},
coverageReporter: {
    type : 'html',
    dir : 'coverage/'
}

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

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

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

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


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

再看覆盖率报告,
karma4

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

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

6. Karma第一次启动时出现的问题

CHROME_BIN的环境变量问题


~ D:\workspace\javascript\karma>karma start karma.conf.js
INFO [karma]: Karma v0.10.2 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
ERROR [launcher]: Cannot start Chrome
        Can not find the binary C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chrome.exe
        Please set env variable CHROME_BIN

设置方法:找到系统中chrome的安装位置,找到chrome.exe文件


~ D:\workspace\javascript\karma>set CHROME_BIN="C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"

转载请注明出处:
http://blog.fens.me/nodejs-karma-jasmine/

打赏作者

This entry was posted in Javascript语言实践

0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

51 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
ss

配置文件中需要引入一个外部的js ‘http://apis.mapabc.com/webapi/auth.json?t=javascriptmap&v=3.1.1&key=ef3bd020f702312e591e771627c57b807ba4c04085c0159d67d8fdcc0f61bb129f3d2a973dfae9a6’, 这种样子的 怎么写呢 发现karma压根没找到

king

好文!Conan有没有配过karma+jasmine+phantomJs的测试?

Conan Zhang

没用过phantomJs

yangchao

为什么我在win7下npm install -g karma,但是使用karma命令时 ,即使我使用全路径D:fekarma>D:nodejsnode_moduleskarmabinkarma start 都不行,报不是内部或外部命令,也不是可运行的程序或批处理文件,请指导一下

Conan Zhang

karma包已经升级了,这篇文章有些地方已经不能运行,查官方网站解决吧。

coocon

sudo npm install -g karma-cli, 需要安装它的命令行包

[…] 测试:jasmine,karma […]

Zimo Zeng

Hello

为什么 在karma start karma.conf.js 提示 错误

ERROR [launcher]: No binary for Chrome browser on your platform.

Please, set “CHROME_BIN” env variable.

后 设置了 CHROME_BIN 再重启 依旧报那个错误
WIN7 系统

Conan Zhang

我不清楚是不是karma新版本所造成的问题,去查一下官方文档吧。

Zimo Zeng

谢谢 搞定了 配置后 需要 再次重启一下 CMD

Conan Zhang

解决就好!

jsers

karma可以测试浏览器的多版本吗

Conan Zhang

浏览器的多版,用js就可以测试,Karma只是一个自动化测试的框架。

coder

安装karma的时候为什么老报这个错:npm WARN optional dep failed, continuing fsevents@0.3.0?

coder

如果要用requireJS 的话 在karma的配置文件里面frameworks: [‘jasmine’, ‘requirejs’],,但是UT 会报这个错误”mismatched anonymous define() module”为什么呢???

Conan Zhang

文章中Karma和jasmine都是基于node的npm进行模块管理的,不需要requirejs。

coder
Conan Zhang

是你的个人网站l吗?

coder

以前的一个同事的

Conan Zhang

博客作者出了本JS的书,还是挺牛的!!

coder

嗯嗯,请问下 我现在想写jquery代码的UT,用karma+jasmine+require ,不知道karma-jquery这个东西你有没有了解,可否给点建议。

coder

我用require是想在写UT的时候,处理文件之间的依赖关系。

coder

$(function(){}) 这种方式的UT 不管我如何将jquery引入进去,都会报错:$ is not defined,我该怎么办???

Conan Zhang

先用传统的方式,整个加载js文件,第二步再使用require重新实现加载器。

coder

我想再问下
1.在karma的配置文件中 file 这个参数 pattern 的方式引用文件和字符串直接引用有什么不同?
例如:{pattern: ‘tested/libs/jquery.js’, included: false, served: true},
和’tested/libs/jquery.js’,
我还发现这个里面的文件加载还必须按照依赖关系来加载.

Conan Zhang

1. pattern是通过正则表达式进行匹配,支持?*,|,[]等语法,这样就不用列出所有的文件了。
2. js在html中加载是有顺序的,如果你用了加载器,它会自动按顺序加载的。
3. 我没有用过karma-coverage,估计应该差不多。

coder

1.karma配置文件中:
preprocessors: {
‘tested/modules/**/script/*.js’: [‘coverage’]
},
不用pattern我这种写法也可以啊,
2.我这块说的加载是kama配置文件里面files:[]的文件加载
3.看你本文 5. Karma和istanbul代码覆盖率 汗~~~

Conan Zhang

1. 你的方式是可以,pattern为了不同人的需求,如果需要排除目录里面的a.js和b.js你怎么写?

2. 我不确定是否有严格的顺序,如果有依赖关系,按顺序加载是很正常的要求。

3. 不知道你的“汗”,是好还是不好。文章只是一个用例,不代表项目中就是100%或者50%。越真实的环境,代码往往也会越复杂,而复杂的JS闭包写法,覆盖就会越低。

coder

1.排除不是可以写在 exclude: [],这个参数底下
3.我的意思是 在本文5 你用了karma-coverage 你却说你没用过,可能是因为时间过去太久了,我’汗’ 只是表示惊讶,并无它意,如有冒犯,I’m so sorry

Conan Zhang

15个月之前的文章了,确实是太久了。当时网上还没有几个写node程序的做自动化测试或持续集成的。

不好意思,我也忘的差不多了。

coder

没事,从接触nodeJs开始,您的很多文章对我很有帮助,希望你早日出本书,我一定会买本正版的>.<

Conan Zhang

多谢支持,Nodejs的书已经提到日程了,希望明年4-5月时可以出版。

coder

上面您提到了闭包对UT的影响,我现在也遇到了这个问题,不知道对于这种问题有什么好的解决方式?

Conan Zhang

1. 匿名闭包,无法测试。
2. 闭包运行时scope不确定,写测试有难度。
3. 通过架构或框架,标准化代码结构,禁止在功能代码中用闭包。

coder

收到,谢谢您的建议,希望和你有更多的交流,谢谢。
预祝你的nodeJs能顺利上市,大获成功

Conan Zhang

🙂

coder

丹哥,我还有个问题想请教下,既然nodeJS是javascript的执行环境,为什么karma执行jasmine的测试用例和监控网文件变化的时候借助浏览器,直接在node的环境下不行吗?

Conan Zhang

1. nodejs和浏览器是两个不同的运行环境

2. Nodejs代码的自动测试在nodejs环境中,浏览器中js代码的自动测试在浏览器环境中。

3. 如果你的代码,需要同时支持两种环境,需要分别在两个环境中都进行测试。

coder

那karma+jasmine的测试代码为什么不直接跑在nodeJS中,而要拉上浏览器。

Conan Zhang

本文给的例子是基于浏览器的,你同样可以在nodejs中运行,看你自己的需求是什么了。

coder

grunt-contrib-jasmine+ phantomJS

Conan Zhang

不清楚karma-jquery,我已经放弃jquery转向angularjs了。

ice cream

请问,测试结果能够保存吗?保存成文档或者HTML方式。

Conan Zhang

可以

damon

安照你说的步骤:在第2部 (2. Karma的安装)
这是打开 http://localhost:9876/
会报错:
You need to include some adapter that implements __karma__.start method。

如果将第3步(3. Karma + Jasmine配置)提前到
# 测试是否安装成功
~ D:workspacejavascriptkarma>karma start
INFO [karma]: Karma v0.10.2 server started at http://localhost:9876/
INFO [Chrome 28.0.1500 (Windows 7)]: Connected on socket nIlM1yUy6ELMp5ZTN9Ek

之前就不会报错了。

damon

在第4步:
4. 自动化单元测试
3). 修改karma.conf.js配置文件

应加上
plugins: [
‘karma-chrome-launcher’,
‘karma-jasmine’
],
否则会出现这样的 warn
WARN [launcher]: Can not load “Chrome”, it is not registered!
Perhaps you are missing some plugin?
而且 chrome浏览器也不会自动打开

Conan Zhang

估计是karma升级的原因吧,文章是1年半之前写的了,需要对应查看官方文档。

lioff

karma 启动的浏览器窗口 只是用来运行 浏览器端 js … 其实可以像jasmine 那样直接把测试结果输出在同一运行窗口里面这样 又直观又避免另外安装html report 插件

Conan Zhang

是的,只是有些情况要在浏览器里运行。

joker

你好,想请教一下,当我用jasmine测试我的前端代码的时候是否真正生成了这个界面?举例解释一下:如果我的方法的结果是弹出了一个弹出框,那我的测试案例中可以通过 document.getElementById(“xxx”) 这种方法来获取节点并断言吗?

Conan Zhang

jasmine只是测试框架,你自己定义好input,output就可以使用。dom节点,只有在浏览器中才有。

51
0
Would love your thoughts, please comment.x
()
x