关于 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 进行单元测试的更多相关文章

  1. 在WebStorm中集成Karma+jasmine进行前端单元测试

    在WebStorm中集成Karma+jasmine进行前端单元测试 前言 好久没有写博了,主要还是太懒=.=,有点时间都去带娃.看书了,今天给大家分享一个原创的小东西,如果大家对TDD或者BDD有兴趣 ...

  2. Karma:2. 集成 Karma 和 mocha 进行单元测试

    上一篇文章讨论了如何集成 Karma 和 Jasmine,地址见:Karma:1. 集成 Karma 和 Jasmine 进行单元测试 这篇文章讨论如何 Karma 集成 mocha 测试框架. 安装 ...

  3. 使用karma+jasmine做单元测试

    目的 使用karma和jasmine来配置自动化的js单元测试. Karma和Jasmine Karma是由Angular团队所开发的一种自动化测试工具.链接:http://karma-runner. ...

  4. Karma和Jasmine自动化单元测试

    从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发.Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎.chrome浏 ...

  5. Karma和Jasmine 自动化单元测试环境搭建

    最近初学AngularJS ,看到的一些教程中经常有人推荐使用Karma+Jasmine来进行单元测试.自己之前也对Jasmine有些了解,jasmine也是一个不错的测试框架. 1. karma介绍 ...

  6. Karma和Jasmine自动化单元测试——本质上还是在要开一个浏览器来做测试

    1. Karma的介绍 Karma是Testacular的新名字,在2012年google开源了Testacular,2013年Testacular改名为Karma.Karma是一个让人感到非常神秘的 ...

  7. Karma 5:集成 Karma 和 Angular2

    集成 Karma 和 Angular2 我们需要做很多工作,由于需要使用 TypeScript 进行开发,首先需要正确配置 Typescript ,然后正确配置对 Angular2 的引用.还要创建 ...

  8. Angularjs 基于karma和jasmine的单元测试

    目录: 1. 单元测试的配置 2. 实例文件目录解释 3. 测试controller     3.1 测试controller中变量值是否正确     3.2 模拟http请求返回值,测试$http服 ...

  9. angularJS+requireJS并集成karma测试实践

    最近在为下一个项目做前端技术选型,Angular是必须要用的(BOSS指定,个人感觉也不错,开发效率会很高).由于需要加载的JS很多,所以打算看看angular和requirejs一起用会怎么样.在g ...

随机推荐

  1. HTML5适合移动应用开发的几大特性

    1.离线缓存为HTML5开发移动应用提供了基础 HTML5 Web Storage API可以看做是加强版的cookie,不受数据大小限制,有更好的弹性以及架构,可以将数据写入到本机的ROM中,还可以 ...

  2. 1、android源代码下载及目录分析,和eclipser的跟踪

    1.在eclipse中跟踪源代码:假如对mainactivity.java里面的activity按Ctrl+鼠标左键(前提已经导入android源代码:方法1:在项目点击右键,然后找到properti ...

  3. 判断CAD版本

    使用命令: ACADVER ACADVER = "17.2s (LMS Tech)" (只读) CAD2016 ACADVER = "20.1s (LMS Tech)&q ...

  4. mysql-5.6.17-win32免安装版配置

    下载mysql-5.6.17-win32:官网下载地址百度   解压到自定义目录,我这里演示的是D:\wamp\mysql\   复制根目录下的my-default.ini,改名为my.ini,my. ...

  5. 黑马程序员——【Java基础】——集合框架

    ---------- android培训.java培训.期待与您交流! ---------- 一.集合框架概述 (一)集合框架中集合类关系简化图 (二)为什么出现集合类? 面向对象语言对事物的体现都是 ...

  6. 如何获取WIN10 Program Files 文件夹下的文件操作权限

    找到指定文件,右键-属性-找到指定用户-授"完全控制权限“--更改文件--恢复默认权限.

  7. python数据结构与算法——归并排序

    归并排序: 原理与C语言实现 参考:白话经典算法系列之五 归并排序的实现 1. 容易对有序数组A,B进行排序. 2. 为了使得A,B组内数据有序:可以将A,B组各自再分成二组. 3. 经过不断分组,当 ...

  8. Java笔记5-修饰符,重载,递归,数组

    方法的定义修饰符 返回类型 方法名(参数列表) throws 异常类型列表 { //方法体}==如何来设计一个方法:案例:请根据如下的业务分别设计出方法1.根据给定的年份判断是否是闰年?public ...

  9. Productivity Power Tools 的使用

    免费的精品: Productivity Power Tools 动画演示 Productivity Power Tools 是微软官方推出的 Visual Studio 扩展,被用以提高开发人员生产率 ...

  10. WebJars 进行 css js 资源文件管理

    WebJars是将这些通用的Web前端资源打包成Java的Jar包,然后借助Maven工具对其管理,保证这些Web资源版本唯一性,升级也比较容易.关于webjars资源,有一个专门的网站http:// ...