Files - 文件项
Karma 使用 minimatch 库来匹配文件。由于 minimatch 本身以方便灵活而著称,同时它的文件表达式又非常的简洁。在配置文件中,下面的这几个部分都会用到这种表达式
exclude
files
preprocessors
例如
**/*.js: 表示在所有的子目录内,以"js"为后缀的那些文件
**/!(jquery).js: 和上面的含义相同,但不包括"jquery.js"文件
**/(foo|bar).js: 表示在所有子目录内,以"foo.js"或者"bar.js"为名称的那些文件
详细的配置项可以参看Karma 官网关于 file 部分
我们以 files 配置项为例,来详细的了解文件匹配的具体用法
files
使用 files 选项,用于告诉 Karma 哪些文件会被项目使用,而哪些文件含有测试用例,以及需要测试。值得注意的是,文件配置的顺序就是浏览器引用它们时的顺序。
匹配模式
所有的相对位置,都是针对 basePath 而言的.
basePath 也可以使用相对位置定义,此时它是相对于配置文件所在的位置
Karma 使用 globa 库来解决文件的位置问题。它支持使用 minimatch 表达式,例如 test/unit/**/*.spec.js.
匹配顺序
模式的顺序决定了文件包含在浏览器中的顺序
如果多个文件被匹配到,文件按照按字母顺序排序
每个文件都包含一次。如果多个模式匹配同一个文件,则文件包含在第一个匹配到的模式中
完整的式例
清单 12. files
files: [ // Detailed pattern to include a file. Similarly other options can be used { pattern: 'lib/angular.js', watched: false }, // Prefer to have watched false for library files. No need to watch them for changes // simple pattern to load the needed testfiles // equal to {pattern: 'test/unit/*.spec.js', //watched: true, served: true, included: true} 'test/unit/*.spec.js', // this file gets served but will be ignored by the watcher // note if html2js preprocessor is active, reference as //`window.__html__['compiled/index.html']` {pattern: 'compiled/index.html', watched: false}, // this file only gets watched and is otherwise ignored {pattern: 'app/index.html', included: false, served: false}, // this file will be served on demand from disk and will be ignored by the watcher {pattern: 'compiled/app.js.map', included: false, served: true, watched: false, nocache: true} ], |
详细解释,请参看 Karma 官网关于 included, watched, served 的解释
Browsers - 浏览器配置
捕获浏览器的行为总是令人感到很沮丧的,无疑这样的工作会耗费大量的开发时间。然而如果使用 Karma,这一切都会变得异常简单。原因是,Karma 都帮你自动完成了!
配置浏览器,我们只需要在配置文件中正确的设置 browsers 项(例如 browsers: ['Chrome']),Karma 后管理这些浏览器,包括启动与关闭它们。
Karma 支持的浏览器
Chrome and Chrome Canary
Firefox
Safari
PhantomJS
JSDOM
Opera
Internet Explorer
SauceLabs
BrowserStack
many more
我们以 Firefox 浏览器为例,首先你需要安装相应的插件
# Install the launcher first with NPM:
$ npm install karma-firefox-launcher --save-dev
接下在,在配置文件中加入新支持的浏览器名称
清单 13. browsers
module.exports = function(config) { config.set({ browsers : ['Chrome', 'Firefox'] }); }; |
默认情况下,在配置文件中 browsers 项是没有被配置的(也就是说它的值是空)
当然,如果你希望使用其他的设备(如 tablet,手机等)来测试的话,只需在设备中打开对应的的浏览器,并访问 http://<hostname>:<port> (默认端口9876)。
另外,可以通过设置<BROWSER>_BIN 环境变量来替换浏览器路径。例如,在 Linux 下修改 Firefox 浏览器路径
# Changing the path to the Firefox binary
$ export FIREFOX_BIN=/usr/local/bin/my-firefox-build
详细解释,请参看 Karma 官网关于浏览器选项的详细配置
Preprocessors 配置
Preprocessors 定义的方法,会在文件被浏览器运行前执行(有点类似 AOP(Aspect-Oriented Programming)的概念)。
Preprocessors 的配置方法如下:
清单 14. preprocessors
preprocessors: { '**/*.coffee': ['coffee'], '**/*.tea': ['coffee'], '**/*.html': ['html2js'] }, |
注意:
在这里,有多个文件表达式都配置了 "coffee" 这个 processor。在 Karma 看来,processor 与表达式的关系,有点类似于数据库里的一对多的关系。也就是说,一个 processor 可以被用于多个文件表达式。而且大多数的 Preprocessors 实现,都需要按照 plugins 的形式加载。
一些经常会用到的 preprocessors,如下
coffee
html2js
coverage
ng-html2js
many more
下面我们以 CoffeScript preprocessor 为例,看看如何在配置文件中使用它
首先我们需要先安装 karma-coffee-preprocessor
# Install it first with NPM
$ npm install karma-coffee-preprocessor --save-dev
接下来在配置文件中,我们需要这样.
清单 15. preprocessors
module.exports = function(config) { config.set({ preprocessors: { '**/*.coffee': ['coffee'] } }); }; |
一些 preprocessors 还支持配置化,例如
清单 16. Preprocessors 配置化
coffeePreprocessor: { options: { bare: false } } |
或者可以通过自定义的 preprocessor 的方式,例如
清单 17. Preprocessors 配置化
customPreprocessors: { bare_coffee: { base: 'coffee', options: {bare: true} } } |
最小匹配 minimatch
在配置 preprocessors 时用到的 key 值,是用来过滤 files 中配置的那些文件。(关于 files 的配置,前面已经介绍过了)
下面我们来详细了解一下过滤的执行步骤
首先,展开文件路径。所有的文件路径都会被展开成绝对路径(依靠 basePath 的位置)。
接下来,将文件路径与配置的 key 值进行匹配(需要使用到 minimatch 库)。
我们以 /my/absolute/path/to/test/unit/file.coffee 路径为例,如果 key 值是是 **/*.coffee 的化,匹配就会成功,但如果 key 值是 *.coffee,匹配则会失败。而文件匹配失败,preprocessor 自然也就不会被执行。
执行顺序
如果一个文件只匹配到了 preprocessors 配置对象的某一个 key 值,那么 Karma 会按照文件当中所描述的顺序依次执行 preprocessors。例如
清单 18. Minimatch 执行顺序
preprocessors: { '*.js': ['a', 'b'] } |
这时,karma 会先执行"a",然后执行"b"
如果一个文件匹配到多个 key 值,Karma 会按照某种合理的顺序执行 preprocessors,例如
清单 19. Minimatch 执行顺序
preprocessors: { '*.js': ['a', 'b'], 'a.*': ['b', 'c'] } |
对于a.js这个文件, karma 会先执行 'a',再执行 'b',最后执行 'c'.
但如果两个列表中的配置有矛盾(也许是配置错误), 例如:
清单 20. Minimatch 执行顺序
preprocessors: { '*.js': ['a', 'b'], 'a.*': ['b', 'a'] } |
那么,此时的 Karma 会随机的挑选一个配置顺序来执行。又比如
清单 21. Minimatch 执行顺序
preprocessors: { '*.js': ['a', 'b', 'c'], 'a.*': ['c', 'b', 'd'] } |
可以确定的是'a'会第一个被执行,'d'会最后一个被执行,而对于'b'和 'c',它们的执行顺序是随机的.
启动 Karma
命令
$ karma start karma.conf.js
有一些配置属性还可以在执行 karma 命令时,以参数的形式进行覆盖,例如
karma start my.conf.js --log-level debug --single-run
此时,Karma 会自动打开浏览器,并运行相应的测试用例,而执行结果会输出到控制台。
图 1. 图片标题示例
Karma 中的 Reporters
在默认的情况下,Karma 会将测试的执行结果显示在控制台上。而有些时候,我们可能更希望使用其他的输出格式,将结果展示出来。或者让 Karma 帮我们做更多的事情,比如显示代码的覆盖率等等,此时,我们就需要 Karma 的报表功能。
Karma 使用 Reporters 来显示执行结果。我们以 karma-html-reporter 为例
首先,我们需要下载 karma-html-reporter
npm install karma-htmlfile-reporter --save-dev
或者,你也可以全局安装
npm install -g karma-htmlfile-reporter
接下来,修改配置文件
清单 22. karma.conf.js
module.exports = function(config) { config.set({ ..... ..... reporters: ['progress', 'html'], htmlReporter: { outputFile: 'test-units.html', // Optional pageTitle: 'Unit Tests', subPageTitle: 'A sample project description', groupSuites: true, useCompactStyle: true, useLegacyStyle: true } }); }; |
执行命令
karma start --reporters html 或者 karma start karma.conf.js
在浏览器正常运行测试用例后,会在执行目录下生成 test-units.html 文件。使用浏览器打开 test-units.html 文件
图 2. 图片标题示例
总结
Karma 与 AngularJS 有着密不可分的联系,也进一步证明了其作为测试运行平台的能力。它出色的架构设计以及灵活的扩展性,也越来越引起众多 JavaScript 社区的关注。
它的特性让人印象深刻
支持多种测试框架
多样的结果报表(Reports)展示
在多种浏览器上运行测试用例
支持多种持续集成框架
简单,快速而有趣
这些特性,使它区别于其他的测试框架与平台,势必会成为开发者不可或缺的工具之一。