Karma:1. 集成 Karma 和 Jasmine 进行单元测试

Karma:1. 集成 Karma 和 Jasmine 进行单元测试

来源:http://www.cnblogs.com/haogj/p/5204126.htmljavascript

关于 Karma 会是一个系列,讨论在各类环境下,使用 Karma 进行单元测试。html

本文讨论 karma 集成 Jasmine 进行单元测试。java

初始化 NPM

实现初始化 NPM 包管理,建立 package.json 项目管理文件。node

使用参数 -y 直接按照默认值建立 packgae.json 项目管理文件。chrome

复制代码
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 文件已经建立了。npm

安装 Karma

如今,能够直接使用 NPM 来安装 karma。json

i 是 install 命令的缩写,-D 是 --save-dev 的缩写。浏览器

复制代码

PS C:\study\mykarma> npm i -D karma npm WARN package.json mykarma@1.0.0 No description npm WARN package.json mykarma@1.0.0 No repository field. npm WARN package.json mykarma@1.0.0 No README data npm WARN optional dep failed, continuing fsevents@1.0.7 karma@0.13.21 node_modules\karma ├── batch@0.5.3 ├── di@0.0.1 ├── graceful-fs@4.1.3 ├── rimraf@2.5.2 ├── mime@1.3.4 ├── colors@1.1.2 ├── source-map@0.5.3 ├── isbinaryfile@3.0.0 ├── bluebird@2.10.2 ├── dom-serialize@2.2.1 (custom-event@1.0.0, void-elements@2.0.1, extend@3.0.0, ent@2.2.0) ├── http-proxy@1.13.2 (eventemitter3@1.1.1, requires-port@1.0.0) ├── optimist@0.6.1 (wordwrap@0.0.3, minimist@0.0.10) ├── glob@7.0.0 (path-is-absolute@1.0.0, inherits@2.0.1, once@1.3.3, inflight@1.0.4) ├── useragent@2.1.8 (lru-cache@2.2.4) ├── minimatch@3.0.0 (brace-expansion@1.1.3) ├── lodash@3.10.1 ├── expand-braces@0.1.2 (array-unique@0.2.1, array-slice@0.2.3, braces@0.1.5) ├── log4js@0.6.31 (semver@4.3.6, readable-stream@1.0.33) ├── connect@3.4.1 (utils-merge@1.0.0, parseurl@1.3.1, debug@2.2.0, finalhandler@0.4.1) ├── core-js@2.1.0 ├── body-parser@1.15.0 (content-type@1.0.1, bytes@2.2.0, depd@1.1.0, raw-body@2.1.5, debug@2.2.0, qs@6.1.0, iconv-lite@0.4.13, http-errors@1.4.0, on-finished@2.3.0, type-is@1.6.11) ├── socket.io@1.4.5 (debug@2.2.0, has-binary@0.1.7, socket.io-parser@2.2.6, socket.io-adapter@0.4.0, engine.io@1.6.8, socket.io-client@1.4.5) └── chokidar@1.4.2 (path-is-absolute@1.0.0, inherits@2.0.1, async-each@0.1.6, glob-parent@2.0.0, is-binary-path@1.0.1, is-glob@2.0.1, readdirp@2.0.0, anymatch@1.3.0) 
PS C:\study\mykarma>
复制代码

如今咱们可使用 node 来运行 karma  了。app

 >node ./node_modules/karma/bin/karma

 

为了能在命令行直接执行 karma 命令,咱们再按着一个 karma-cli.dom

-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.2 C:\Users\guanjun\AppData\Roaming\npm\node_modules\karma-cli └── resolve@1.1.7

安装以后,能够直接使用 karma 来启动测试了,首先检查一下当前的版本。

PS C:\study\mykarma> karma --version
Karma version: 0.13.21 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.0 No description npm WARN package.json mykarma@1.0.0 No repository field. npm WARN package.json mykarma@1.0.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 3+. Your application will need to depend on it explicitly. jasmine-core@2.4.1 node_modules\jasmine-core karma-jasmine@0.3.7 node_modules\karma-jasmine karma-chrome-launcher@0.2.2 node_modules\karma-chrome-launcher ├── fs-access@1.0.0 (null-check@1.0.0) └── which@1.2.4 (isexe@1.1.2, is-absolute@0.1.7) 
复制代码

 如今涉及单元测试的基本工具已经安装就绪了。

  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 20 02 2016 22:32:26.698:WARN [init]: There is no file matching this pattern. > test/**/*.spec.js 20 02 2016 22:33: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
22 02 2016 10:54:11.796:INFO [karma]: Karma v0.13.21 server started at http://localhost:9876/ 22 02 2016 10:54:11.806:INFO [launcher]: Starting browser Chrome 22 02 2016 10:54:13.206:INFO [Chrome 47.0.2526 (Windows 7 0.0.0)]: Connected on socket /#rbiYFxG0uTVJxpVoAAAA with id 13601272

 

 

单元测试

成功和失败

如今咱们可使用 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
22 02 2016 11:09:31.137:WARN [karma]: No captured browser, open http://localhost:9876/ 22 02 2016 11:09:31.157:INFO [karma]: Karma v0.13.21 server started at http://localhost:9876/ 22 02 2016 11:09:31.167:INFO [launcher]: Starting browser Chrome 22 02 2016 11:09:32.561:INFO [Chrome 47.0.2526 (Windows 7 0.0.0)]: Connected on socket /#ymfXfb-xI2a3fZ82AAAA with id 31292195 Chrome 47.0.2526 (Windows 7 0.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:7:20) Chrome 47.0.2526 (Windows 7 0.0.0): Executed 2 of 2 (1 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
22 02 2016 11:22:18.800:WARN [karma]: No captured browser, open http://localhost:9876/ 22 02 2016 11:22:18.810:INFO [karma]: Karma v0.13.21 server started at http://localhost:9876/ 22 02 2016 11:22:18.820:INFO [launcher]: Starting browser Chrome 22 02 2016 11:22:20.232:INFO [Chrome 47.0.2526 (Windows 7 0.0.0)]: Connected on socket /#i6GaDaxNTy8HWL52AAAA with id 89457157 Chrome 47.0.2526 (Windows 7 0.0.0) add function unit test. 2 + 3 = 6, this should faild. FAILED Expected 5 to be 6. at Object.<anonymous> (C:/study/mykarma/test/unit/add.spec.js:9:24) Chrome 47.0.2526 (Windows 7 0.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:7:20) Chrome 47.0.2526 (Windows 7 0.0.0): Executed 4 of 4 (2 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 测试是很方便的组合。

相关文章
相关标签/搜索