从零开始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/
前言
在Java领域,Apache, Spring, JBoss 三大社区的开源库,包罗万象,但每个库都在其领域中都鹤立鸡群。而Nodejs中各种各样的开源库,却让人眼花缭乱,不知从何下手。
Nodejs领域: Jasmine做单元测试,Karma自动化完成单元测试,Grunt启动Karma统一项目管理,Yeoman最后封装成一个项目原型模板,npm做nodejs的包依赖管理,bower做javascript的包依赖管理。Java领域:JUnit做单元测试, Maven自动化单元测试,统一项目管理,构建项目原型模板,包依赖管理。
Nodejs让组合变得更丰富,却又在加重我们的学习门槛。我还说不清楚,也看不透!
上面写的有点远了,回到文章的主题,Jasmine+Karma自动化单元测试。
目录
- Karma的介绍
- Karma的安装
- Karma + Jasmine配置
- 自动化单元测试
- Karma和istanbul代码覆盖率
- 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界面。
下面我们要开始配置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
我们修改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
覆盖率是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的代码测试及覆盖率研究,我还要做更多的验证。
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"
配置文件中需要引入一个外部的js ‘http://apis.mapabc.com/webapi/auth.json?t=javascriptmap&v=3.1.1&key=ef3bd020f702312e591e771627c57b807ba4c04085c0159d67d8fdcc0f61bb129f3d2a973dfae9a6’, 这种样子的 怎么写呢 发现karma压根没找到
好文!Conan有没有配过karma+jasmine+phantomJs的测试?
没用过phantomJs
为什么我在win7下npm install -g karma,但是使用karma命令时 ,即使我使用全路径D:fekarma>D:nodejsnode_moduleskarmabinkarma start 都不行,报不是内部或外部命令,也不是可运行的程序或批处理文件,请指导一下
karma包已经升级了,这篇文章有些地方已经不能运行,查官方网站解决吧。
sudo npm install -g karma-cli, 需要安装它的命令行包
[…] 测试:jasmine,karma […]
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 系统
我不清楚是不是karma新版本所造成的问题,去查一下官方文档吧。
谢谢 搞定了 配置后 需要 再次重启一下 CMD
解决就好!
karma可以测试浏览器的多版本吗
浏览器的多版,用js就可以测试,Karma只是一个自动化测试的框架。
安装karma的时候为什么老报这个错:npm WARN optional dep failed, continuing fsevents@0.3.0?
如果要用requireJS 的话 在karma的配置文件里面frameworks: [‘jasmine’, ‘requirejs’],,但是UT 会报这个错误”mismatched anonymous define() module”为什么呢???
文章中Karma和jasmine都是基于node的npm进行模块管理的,不需要requirejs。
http://icodeit.org/
是你的个人网站l吗?
以前的一个同事的
博客作者出了本JS的书,还是挺牛的!!
嗯嗯,请问下 我现在想写jquery代码的UT,用karma+jasmine+require ,不知道karma-jquery这个东西你有没有了解,可否给点建议。
我用require是想在写UT的时候,处理文件之间的依赖关系。
$(function(){}) 这种方式的UT 不管我如何将jquery引入进去,都会报错:$ is not defined,我该怎么办???
先用传统的方式,整个加载js文件,第二步再使用require重新实现加载器。
我想再问下
1.在karma的配置文件中 file 这个参数 pattern 的方式引用文件和字符串直接引用有什么不同?
例如:{pattern: ‘tested/libs/jquery.js’, included: false, served: true},
和’tested/libs/jquery.js’,
我还发现这个里面的文件加载还必须按照依赖关系来加载.
1. pattern是通过正则表达式进行匹配,支持?*,|,[]等语法,这样就不用列出所有的文件了。
2. js在html中加载是有顺序的,如果你用了加载器,它会自动按顺序加载的。
3. 我没有用过karma-coverage,估计应该差不多。
1.karma配置文件中:
preprocessors: {
‘tested/modules/**/script/*.js’: [‘coverage’]
},
不用pattern我这种写法也可以啊,
2.我这块说的加载是kama配置文件里面files:[]的文件加载
3.看你本文 5. Karma和istanbul代码覆盖率 汗~~~
1. 你的方式是可以,pattern为了不同人的需求,如果需要排除目录里面的a.js和b.js你怎么写?
2. 我不确定是否有严格的顺序,如果有依赖关系,按顺序加载是很正常的要求。
3. 不知道你的“汗”,是好还是不好。文章只是一个用例,不代表项目中就是100%或者50%。越真实的环境,代码往往也会越复杂,而复杂的JS闭包写法,覆盖就会越低。
1.排除不是可以写在 exclude: [],这个参数底下
3.我的意思是 在本文5 你用了karma-coverage 你却说你没用过,可能是因为时间过去太久了,我’汗’ 只是表示惊讶,并无它意,如有冒犯,I’m so sorry
15个月之前的文章了,确实是太久了。当时网上还没有几个写node程序的做自动化测试或持续集成的。
不好意思,我也忘的差不多了。
没事,从接触nodeJs开始,您的很多文章对我很有帮助,希望你早日出本书,我一定会买本正版的>.<
多谢支持,Nodejs的书已经提到日程了,希望明年4-5月时可以出版。
上面您提到了闭包对UT的影响,我现在也遇到了这个问题,不知道对于这种问题有什么好的解决方式?
1. 匿名闭包,无法测试。
2. 闭包运行时scope不确定,写测试有难度。
3. 通过架构或框架,标准化代码结构,禁止在功能代码中用闭包。
收到,谢谢您的建议,希望和你有更多的交流,谢谢。
预祝你的nodeJs能顺利上市,大获成功
🙂
丹哥,我还有个问题想请教下,既然nodeJS是javascript的执行环境,为什么karma执行jasmine的测试用例和监控网文件变化的时候借助浏览器,直接在node的环境下不行吗?
1. nodejs和浏览器是两个不同的运行环境
2. Nodejs代码的自动测试在nodejs环境中,浏览器中js代码的自动测试在浏览器环境中。
3. 如果你的代码,需要同时支持两种环境,需要分别在两个环境中都进行测试。
那karma+jasmine的测试代码为什么不直接跑在nodeJS中,而要拉上浏览器。
本文给的例子是基于浏览器的,你同样可以在nodejs中运行,看你自己的需求是什么了。
grunt-contrib-jasmine+ phantomJS
不清楚karma-jquery,我已经放弃jquery转向angularjs了。
请问,测试结果能够保存吗?保存成文档或者HTML方式。
可以
安照你说的步骤:在第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
之前就不会报错了。
在第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浏览器也不会自动打开
估计是karma升级的原因吧,文章是1年半之前写的了,需要对应查看官方文档。
karma 启动的浏览器窗口 只是用来运行 浏览器端 js … 其实可以像jasmine 那样直接把测试结果输出在同一运行窗口里面这样 又直观又避免另外安装html report 插件
是的,只是有些情况要在浏览器里运行。
你好,想请教一下,当我用jasmine测试我的前端代码的时候是否真正生成了这个界面?举例解释一下:如果我的方法的结果是弹出了一个弹出框,那我的测试案例中可以通过 document.getElementById(“xxx”) 这种方法来获取节点并断言吗?
jasmine只是测试框架,你自己定义好input,output就可以使用。dom节点,只有在浏览器中才有。