Karma:1. 集成 Karma 和 Jasmine 进行单元测试
关于 Karma 会是一个系列,讨论在各种环境下,使用 Karma 进行单元测试。
本文讨论 karma 集成 Jasmine 进行单元测试。
初始化 NPM
实现初始化 NPM 包管理,创建 package.json 项目管理文件。
使用参数 -y 直接按照默认值创建 packgae.json 项目管理文件。
PS C:\study\mykarma> npm init -y
Wrote to C:\study\mykarma\package.json: {
"name": "mykarma",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
现在,可以在项目文件夹中看到 package.json 文件已经创建了。
安装 Karma
现在,可以直接使用 NPM 来安装 karma。
i 是 install 命令的缩写,-D 是 --save-dev 的缩写。
PS C:\study\mykarma> npm i -D karma
npm WARN package.json mykarma@1.0. No description
npm WARN package.json mykarma@1.0. No repository field.
npm WARN package.json mykarma@1.0. No README data
npm WARN optional dep failed, continuing fsevents@1.0.
karma@0.13. node_modules\karma
├── batch@0.5.
├── di@0.0.
├── graceful-fs@4.1.
├── rimraf@2.5.
├── mime@1.3.
├── colors@1.1.
├── source-map@0.5.
├── isbinaryfile@3.0.
├── bluebird@2.10.
├── dom-serialize@2.2. (custom-event@1.0., void-elements@2.0., extend@3.0., ent@2.2.)
├── http-proxy@1.13. (eventemitter3@1.1., requires-port@1.0.)
├── optimist@0.6. (wordwrap@0.0., minimist@0.0.)
├── glob@7.0. (path-is-absolute@1.0., inherits@2.0., once@1.3., inflight@1.0.)
├── useragent@2.1. (lru-cache@2.2.)
├── minimatch@3.0. (brace-expansion@1.1.)
├── lodash@3.10.
├── expand-braces@0.1. (array-unique@0.2., array-slice@0.2., braces@0.1.)
├── log4js@0.6. (semver@4.3., readable-stream@1.0.)
├── connect@3.4. (utils-merge@1.0., parseurl@1.3., debug@2.2., finalhandler@0.4.)
├── core-js@2.1.
├── body-parser@1.15. (content-type@1.0., bytes@2.2., depd@1.1., raw-body@.1.5, debug@2.2., qs@6.1., iconv-lite@0.4., http-errors@1.4., on-finished@.3.0, type-is@1.6.)
├── socket.io@1.4. (debug@2.2., has-binary@0.1., socket.io-parser@2.2., socket.io-adapter@0.4., engine.io@1.6., socket.io-client@1.4.)
└── chokidar@1.4. (path-is-absolute@1.0., inherits@2.0., async-each@0.1., glob-parent@2.0., is-binary-path@1.0., is-glob@2.0., readdirp@2.0., anymatch@.3.0)
PS C:\study\mykarma>
现在我们可以使用 node 来运行 karma 了。
>node ./node_modules/karma/bin/karma
为了能在命令行直接执行 karma 命令,我们再按着一个 karma-cli.
-g 表示全局安装,这样可以在系统的任何文件夹中直接执行 karma 命令。
PS C:\study\mykarma> npm i -g karma-cli
C:\Users\XXX\AppData\Roaming\npm\karma -> C:\Users\XXX\AppData\Roaming\npm\node_modules\karma-cli\bin\karma
karma-cli@0.1. C:\Users\guanjun\AppData\Roaming\npm\node_modules\karma-cli
└── resolve@1.1.
安装之后,可以直接使用 karma 来启动测试了,首先检查一下当前的版本。
PS C:\study\mykarma> karma --version
Karma version: 0.13.
PS C:\study\mykarma>
祝贺你, 基本的 Karma 已经安装成功了。
安装 Jasmine 和 chrome-launcher
我们使用 Karma 来驱动单元测试,所以只有 Karma 是不行的,还需要安装单元测试库以便运行测试脚本,安装测试库与 Karma 的适配器,还有各种浏览器的适配器。
这里我们安装 Jasmine 的测试支持和 chrome 浏览器的适配器。
对于 jasmine 来说,我们需要 Jasmine 的适配器,还必须有 jasmine-core 库。
karma-chrome-launcher 则提供了 karma 与 chrome 的适配器。
PS C:\study\mykarma> npm i -D jasmine-core karma-jasmine karma-chrome-launcher
npm WARN package.json mykarma@1.0. No description
npm WARN package.json mykarma@1.0. No repository field.
npm WARN package.json mykarma@1.0. No README data
npm WARN peerDependencies The peer dependency jasmine-core@* included from karma-jasmine will no
npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency
npm WARN peerDependencies in npm +. Your application will need to depend on it explicitly.
jasmine-core@2.4. node_modules\jasmine-core karma-jasmine@0.3. node_modules\karma-jasmine karma-chrome-launcher@0.2. node_modules\karma-chrome-launcher
├── fs-access@1.0. (null-check@1.0.)
└── which@1.2. (isexe@1.1., is-absolute@0.1.)
现在涉及单元测试的基本工具已经安装就绪了。
Karma 的命令
karma 支持三个命令。
- start [<configFile>] [<options>] 启动 Karma 持续执行,也可以执行单次的测试,然后直接收集测试结果.
- init [<configFile>] 初始化配置文件.
- run [<options>] [ -- <clientArgs>] Trigger a test run.
创建 karma 配置文件
Karma 需要进行配置,配置文件比较复杂,可以使用 karma 提供的 init 命令来直接创建基础的配置文件。在处理过程中,我们可以使用交互方式提供测试的信息,Karma 根据这些信息生成一个基本的配置文件。配置文件的默认名称是 karma.conf.js。如果你提供了配置文件的名称,karma 会将配置信息写入到你提供的文件名中。
创建 Karma 配置文件
PS C:\study\mykarma> 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 qu
ion.
> 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
::26.698:WARN [init]: There is no file matching this pattern. > test/**/*.spec.js
::26.513:WARN [init]: There is no file matching this pattern. > 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 "C:\study\mykarma\karma.conf.js". PS C:\study\mykarma>
由于我们没有提供配置文件名称,这里生成的是默认的配置文件 karma.conf.js 。
启动 Karma
由于已经有了 karma 配置文件,现在可以使用 karma start 启动 karma 了,由于还没有测试,所以看不到测试结果是正常的。
需要注意的是 karma 配置中的 singleRun 这个参数,设置为 false 的话,karma 会自动监控测试环境,默认是 Chrome, 如果你关掉了,karma 会自动重新启动一个。如果配置为 true,执行一次测试之后,karma 会自动停掉。
在 singleRun 为 false 的情况下,执行的结果可能是这样的。
PS C:\study\mykarma> karma start
::11.796:INFO [karma]: Karma v0.13.21 server started at http://localhost:9876/
::11.806:INFO [launcher]: Starting browser Chrome
::13.206:INFO [Chrome 47.0. (Windows 0.0.)]: Connected on socket /#rbiYFxG0uTVJxpVoAAAA with id
单元测试
成功和失败
现在我们可以使用 Jasmine 开始写测试了。
在项目文件夹中,创建一个名为 test 的子文件夹来保存测试用例。然后在 test 文件夹中创建一个 unit 的文件夹来保存单元测试用例。
在这个文件夹中创建一个名为 hello.spec.js 的测试文件。
一般来说,我们会为测试用例的文件名称提供一个特定的模式,以便对测试用例进行统一处理,这里我们约定测试用例的文件名以 .spec.js 为结尾。
hello.spec.js
describe('hello, unit test.', function(){
it('should also be able to test', function(){
expect(true).toBe(true);
}); it('should be failed', function(){
expect(true).toBe(false);
})
});
这个测试包含了两个测试用例,一个一定成功,一个一定失败。
确认在我们 karma 的配置文件中,包含了我们的测试用例。
// list of files / patterns to load in the browser
files: [
'test/**/*.spec.js'
],
现在,使用 karma start 启动测试,在控制台应该会看到如下的输出。
PS C:\study\mykarma> karma start
::31.137:WARN [karma]: No captured browser, open http://localhost:9876/
::31.157:INFO [karma]: Karma v0.13.21 server started at http://localhost:9876/
::31.167:INFO [launcher]: Starting browser Chrome
::32.561:INFO [Chrome 47.0. (Windows 0.0.)]: Connected on socket /#ymfXfb-xI2a3fZ82AAAA with id
Chrome 47.0. (Windows 0.0.) hello, unit test. should be failed FAILED
Expected true to be false.
at Object.<anonymous> (C:/study/mykarma/test/unit/hello.spec.js::)
Chrome 47.0. (Windows 0.0.): Executed of ( FAILED) (0.016 secs / 0.006 secs)
可以看到执行了两个测试,其中一个失败了,失败的测试为 hello, unit test 中的 should be failed 测试用例。
测试实际的代码
在项目文件夹中,创建一个名为 src 的子文件夹来保存我们的应用代码,在其中创建一个名为 add.js 的脚本文件,我们将来测试它的工作是否正确。
function add(a, b){
return a + b;
}
这个脚本非常简单,仅仅用来计算两个数字之后,没有任何的验证。
然后,我们针对它写两个测试用例,保存到 ./test/unit/add.spec.js 文件中。
describe('add function unit test.', function(){
it('2 + 3 = 5', function(){
var result = add( 2, 3 );
expect( result ).toBe( 5 );
}); it('2 + 3 = 6, this should faild.', function(){
var result = add( 2, 3 );
expect(result).toBe( 6 );
})
});
确认你的 karma 配置文件中,包含了被测试代码和测试代码。
// list of files / patterns to load in the browser
files: [
'src/**/*.js',
'test/**/*.spec.js'
],
现在的控制台输出应该是这样的。
PS C:\study\mykarma> karma start
::18.800:WARN [karma]: No captured browser, open http://localhost:9876/
::18.810:INFO [karma]: Karma v0.13.21 server started at http://localhost:9876/
::18.820:INFO [launcher]: Starting browser Chrome
::20.232:INFO [Chrome 47.0. (Windows 0.0.)]: Connected on socket /#i6GaDaxNTy8HWL52AAAA with id
Chrome 47.0. (Windows 0.0.) add function unit test. + = , this should faild. FAILED
Expected to be .
at Object.<anonymous> (C:/study/mykarma/test/unit/add.spec.js::)
Chrome 47.0. (Windows 0.0.) hello, unit test. should be failed FAILED
Expected true to be false.
at Object.<anonymous> (C:/study/mykarma/test/unit/hello.spec.js::)
Chrome 47.0. (Windows 0.0.): Executed of ( FAILED) (0.021 secs / 0.007 secs)
祝贺你,现在你已经可以测试你的代码了!
如果你的应用是由一个一个独立的函数定义出来的,现在就已经可以进行测试了。
Karma 执行原理
在 Karma 启动的浏览器界面中,可以看到当前的执行状态。
点击 DEBUG 按钮,可以进入实际的测试页面。
这个页面看起来是空白的,但是执行了实际的测试脚本,进入浏览器的开发者模式,可以看到实际的内容。比如,我们上面的实际执行内容。
查看页面源码,可以看到这个 Karma 生成的页面。
<!doctype html>
<!--
This file is almost the same as context.html - loads all source files,
but its purpose is to be loaded in the main frame (not within an iframe),
just for immediate execution, without reporting to Karma server.
-->
<html>
<head>
<title>Karma DEBUG RUNNER</title>
<link href="favicon.ico" rel="icon" type="image/x-icon" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
</head>
<body>
<!-- The scripts need to be at the end of body, so that some test running frameworks
(Angular Scenario, for example) need the body to be loaded so that it can insert its magic
into it. If it is before body, then it fails to find the body and crashes and burns in an epic
manner. -->
<script type="text/javascript">
window.__karma__ = {
info: function(info) {
if (info.dump && window.console) window.console.log(info.dump);
},
complete: function() {
if (window.console) window.console.log('Skipped ' + this.skipped + ' tests');
},
store: function() {},
skipped: 0,
result: window.console ? function(result) {
if (result.skipped) {
this.skipped++;
return;
}
var msg = result.success ? 'SUCCESS ' : 'FAILED ';
window.console.log(msg + result.suite.join(' ') + ' ' + result.description); for (var i = 0; i < result.log.length; i++) {
window.console.error(result.log[i]);
}
} : function() {},
loaded: function() {
this.start();
}
}; window.__karma__.config = {"args":[],"useIframe":true,"captureConsole":true,"clearContext":true}; // All served files with the latest timestamps
window.__karma__.files = {
'/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js': '391e45351df9ee35392d2e5cb623221a969fc009',
'/base/node_modules/karma-jasmine/lib/boot.js': '4a7da64f416169520c9d5c43b5a7feac6bde9104',
'/base/node_modules/karma-jasmine/lib/adapter.js': 'd76809fbd57147a108ceb7fe2c134b2d39806a9a',
'/base/src/add.js': 'dd99cc5693226f200581da90d5f231a95e6bb720',
'/base/test/unit/add.spec.js': 'f430471235f184ab5e13c14ccb87740b833487d6',
'/base/test/unit/hello.spec.js': '5b7173f9c7e05f6aadc798a5065cd6dc572d005d'
}; </script>
<!-- Dynamically replaced with <script> tags -->
<script type="text/javascript" src="/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script type="text/javascript" src="/base/node_modules/karma-jasmine/lib/boot.js"></script>
<script type="text/javascript" src="/base/node_modules/karma-jasmine/lib/adapter.js"></script>
<script type="text/javascript" src="/base/src/add.js"></script>
<script type="text/javascript" src="/base/test/unit/add.spec.js"></script>
<script type="text/javascript" src="/base/test/unit/hello.spec.js"></script>
<script type="text/javascript">
window.__karma__.loaded();
</script>
</body>
</html>
关键的内容在页面的后部。
<!-- Dynamically replaced with <script> tags -->
<script type="text/javascript" src="/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script type="text/javascript" src="/base/node_modules/karma-jasmine/lib/boot.js"></script>
<script type="text/javascript" src="/base/node_modules/karma-jasmine/lib/adapter.js"></script>
<script type="text/javascript" src="/base/src/add.js"></script>
<script type="text/javascript" src="/base/test/unit/add.spec.js"></script>
<script type="text/javascript" src="/base/test/unit/hello.spec.js"></script>
<script type="text/javascript">
window.__karma__.loaded();
</script>
在这个页面,我们可以在源码中设置断点,检查测试。
总结
可以看到,使用 Karma 集成 Jasmine 测试是很方便的组合。
Karma:1. 集成 Karma 和 Jasmine 进行单元测试的更多相关文章
- 在WebStorm中集成Karma+jasmine进行前端单元测试
在WebStorm中集成Karma+jasmine进行前端单元测试 前言 好久没有写博了,主要还是太懒=.=,有点时间都去带娃.看书了,今天给大家分享一个原创的小东西,如果大家对TDD或者BDD有兴趣 ...
- Karma:2. 集成 Karma 和 mocha 进行单元测试
上一篇文章讨论了如何集成 Karma 和 Jasmine,地址见:Karma:1. 集成 Karma 和 Jasmine 进行单元测试 这篇文章讨论如何 Karma 集成 mocha 测试框架. 安装 ...
- 使用karma+jasmine做单元测试
目的 使用karma和jasmine来配置自动化的js单元测试. Karma和Jasmine Karma是由Angular团队所开发的一种自动化测试工具.链接:http://karma-runner. ...
- Karma和Jasmine自动化单元测试
从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发.Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎.chrome浏 ...
- Karma和Jasmine 自动化单元测试环境搭建
最近初学AngularJS ,看到的一些教程中经常有人推荐使用Karma+Jasmine来进行单元测试.自己之前也对Jasmine有些了解,jasmine也是一个不错的测试框架. 1. karma介绍 ...
- Karma和Jasmine自动化单元测试——本质上还是在要开一个浏览器来做测试
1. Karma的介绍 Karma是Testacular的新名字,在2012年google开源了Testacular,2013年Testacular改名为Karma.Karma是一个让人感到非常神秘的 ...
- Karma 5:集成 Karma 和 Angular2
集成 Karma 和 Angular2 我们需要做很多工作,由于需要使用 TypeScript 进行开发,首先需要正确配置 Typescript ,然后正确配置对 Angular2 的引用.还要创建 ...
- Angularjs 基于karma和jasmine的单元测试
目录: 1. 单元测试的配置 2. 实例文件目录解释 3. 测试controller 3.1 测试controller中变量值是否正确 3.2 模拟http请求返回值,测试$http服 ...
- angularJS+requireJS并集成karma测试实践
最近在为下一个项目做前端技术选型,Angular是必须要用的(BOSS指定,个人感觉也不错,开发效率会很高).由于需要加载的JS很多,所以打算看看angular和requirejs一起用会怎么样.在g ...
随机推荐
- OC基础--Hello Shit
/* Foundation.h为主头文件, 主头文件中又拷贝了该工具箱中所有工具的头文件, 我们只需要导入主头文件就可以使用该工具箱中所有的工具, 避免了每次使用都要导入一个对应的头文件 工具箱的 ...
- Servlet路径跳转2--在servlet当中,跳转到某网页时的路径写法
课程1-13 http://www.imooc.com/video/5554 Servlet路径跳转: 绝对路径:放在任何地方都对的路径 相对路径:相对于当前资源的路径 两种方法:请求重定向,服务 ...
- AngularJS向指令传递数据
我今天要实现的功能是利用AngularJS来完成客户端过滤器. list.html页面主要代码如下: ...... <div class='tj_con_tr_ipt' ng-init=&quo ...
- Serv-U FTP之PASV和PORT模式
Serv-U 设置好后,访问,却提示如下错误:ftp服务器上的文件夹时发生错误,请检查是否有权限访问该文件夹.在解决此问题前,我亲自遇到该问题,看看我查的资料 FTP的连接一般是有两个连接的,一个是客 ...
- java堆、栈、堆栈的区别
1.栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 2. 栈的优势是,存取速度比堆要快,仅次于直接位于CP ...
- Windows Server 2008(R2)配置apache+php+mysql环境问题事项
服务器环境:Windows 2008 R2 64位.apache,mysql,php都是32位. 1. 80端口的外网访问问题 表现:80端口本地可以访问,外网不能访问,换了8080端口也是一样,检查 ...
- jquery操作select(增加,删除,清空)
jQuery获取Select选择的Text和Value: $("#select_id").change(function(){//code...}); //为Select添加事件, ...
- Unity3D 发布无边框exe
关于:Unity3D 发布无边框exe,Unity3D Build exe无边框 Unity发布windows版本 总是带着边框,很想给它去掉,笔者在网上查了一番,常见的有3中. 1:通过unity3 ...
- block捕获自动变量和对象
一.捕获自动变量值 首先看一个经典block面试题: int val = 10; void (^blk)(void) = ^{printf("val=%d\n",val);}; v ...
- Windowns的GVIM添加markdown语法支持
gvim 7.4中其实也是有对markdown的语法文件,但格式支持并不全面,如行业代码``就没有实现. 修改方案: 从github下载plasticboy的markdown语法版本,windowns ...