最近学习Vue框架,想尝试编写Vue单元测试时,发现官方推荐了这个工具。自己也是新入坑,下面的内容可能存在错误,还请斧正。
本文中的例子代码下载。
什么是Karma
网上搜索一番后,了解到Karma就是一个测试运行器。个人理解就是把我们测试过程中编写的测试用例,通过它调用浏览器来运行这些测试用例,然后再汇集测试结果,生成测试报告。
安装
Karma依赖NodeJs
和NPM
包管理工具,安装前建议先将这两个工具升级到最新版本。如果需要使用多个版本的NodeJs
,建议使用NVM
来管理NodeJs
版本。
首先新建一个目录来执行整个过程
$ mkdir karma-intro
$ cd karma-intro
如无特殊说明,下面的所有命令都是在karma-intro
根目录下执行的。
安装karma(强烈建议使用yarn代替npm安装包,速度真的快很多)
$ yarn add karma
运行 karma
$ node_modules/.bin/karma start
每次启动karma如果都输入node_modules/.bin/karma
这么长一串的话,肯定会很不爽。可以通过全局安装karma-cli
$ yarn global add karma-cli
现在,我们便可以在命令行里直接调用karma
命令了,它会自动调用项目里的karma
版本。
$ karma start
配置
安装好Karma之后,我们需要配置它来使用,直接运行命令karma init
可以开启配置向导。根据自己的需要配置。通过tab键可以看到每个问题的答案选项
$ karma init
# 选择测试框架,这里我选择mocha
Which testing framework do you want to use ?
Press tab to list possible options. Enter to move to the next question.
> mocha
# 是否引入Require.js,不需要
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
# 选择使用的浏览器,可以使用无头浏览器PhantomJS,不过需要单独安装PhantomJS
# 这里也可以选择多个浏览器,测试用例将在多个浏览器里执行
# 这里我只选择了Chrome
Do you want to capture any browsers 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.
> test/*.js
10 05 2017 15:00:08.723: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 "/Users/linliang/Src/frontend/karma-intro/karma.conf.js".
命令运行完成后,我们可以看到在当前目录下生成了karma.conf.js
文件。同时,根据我们的配置情况,package.json
里也多了一些依赖项。如我的package.json
里,就多了
"devDependencies": {
"karma-chrome-launcher": "^2.1.1",
"karma-mocha": "^1.3.0"
}
因为我们选择的是使用mocha框架和chrome,所以自动添加了这两个Karma插件。
安装新增加的插件
# 自动安装新添加到依赖里的karma插件
$ yarn
# 安装mocha框架
$ yarn add mocha
编写第一个测试用例
基本的配置文件和依赖都准备就绪后,让我们来尝试编写第一个测试用例。创建
test/hello.js
describe('A spec suite', function() {
it('contains a passing spec', function() {
console.log("Hello Karma");
});
});
测试用例的内容很简单,就是打印一个Hello Karma
信息。
注意: 这里的测试用例文件保存路径就是在我们初始化配置文件时指定的
# 告诉需要执行的测试用例的代码路径,支持正则
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.
> test/*.js
10 05 2017 15:00:08.723:WARN [init]: There is no file matching this pattern.
因此测试用例的保存位置必须满足上面的配置,不然的话Karma会找不到测试文件。
当然,也可以手动修改karma.conf.js
文件的files
部分来指定。
// list of files / patterns to load in the browser
files: [
'test/*.js'
],
如果你的配置文件和我不一样,那么测试用例的文件的保存位置也要做相应的改动。
运行测试用例
浏览器上运行测试用例
为了运行测试用例,我们需要先运行Karma
$ karma start
10 05 2017 15:37:19.619:INFO [karma]: Karma v1.7.0 server started at http://0.0.0.0:9876/
10 05 2017 15:37:19.623:INFO [launcher]: Launching browser Chrome with unlimited concurrency
10 05 2017 15:37:19.632:INFO [launcher]: Starting browser Chrome
10 05 2017 15:37:21.287:INFO [Chrome 57.0.2987 (Mac OS X 10.12.4)]: Connected on socket 5ojH0YX9XIbllG7TAAAA with id 51036312
可以看到它会打开Chrome浏览器,并自动打开了如下图的页面
Karma主页
我们点击页面绿色条右侧的DEBUG
按钮,同时打开浏览器的控制台,就可以看到测试用例已经执行
从上图可以看到,浏览器运行了hello.js
文件,输出了结果
命令行运行测试用例
上面运行测试用例感觉有点麻烦,有没有简单点的方法呢?答案是有的,保留运行karma start
命令的窗口不关闭,新打开一个窗口直接执行命令
$ karma run
LOG: 'Hello Karma'
Chrome 57.0.2987 (Mac OS X 10.12.4): Executed 1 of 1 SUCCESS (0.01 secs / 0.001 secs)
运行特定的测试用例
karma run
默认情况下会一次运行所有找到的测试用例,当我们的测试用例越来越多时,有时候为了方便测试,我们可能需要运行特定的测试用例,那该怎么办呢?
$ karma run -- --grep 'A spec suite'
上面命令中第一个--
表示后面的选项--grep 'A spec suite'
是传递给测试框架的选项,我们这里就是指mocha
。
相当于执行
$ mocha --grep 'A spec suite'`
表示只运行匹配特定字符串A spec suite
的测试用例。
ES6转换
现在基本都流行用ES6语法,但是目前的浏览器对ES6语法的支持并不全,为了兼容性,我们一般会用Babel
把ES6语法转换成ES5,以便浏览器能够兼容。那么我们的Karma运行的测试用例怎么调用Babel做语法转换呢?
让我们创建一个使用了ES6箭头函数的测试用例
test/es6.js
describe('ES6 spec', function() {
it('es6 arrows feature ', function() {
var add = (x, y) => x + y
console.log(add(3,1))
});
});
运行该测试用例
$ karma run -- --grep 'ES6 spec'
LOG: 4
Chrome 57.0.2987 (Mac OS X 10.12.4): Executed 1 of 1 SUCCESS (0.009 secs / 0.002 secs)
再打开浏览器,运行测试用例,我们可以看到浏览器里运行的es6.js
文件。
由于现在的Chrome浏览器已经支持90%的ES6的语法特性,所以这个测试用例能运行成功,没有问题。但是如果浏览器不支持,那么这个测试用例就会运行失败。
PS:
本来想找一个Chrome不支持的ES6特性来做例子,可是发现好像除了import
和export
外,其它的ES6特性Chrome都支持了。而import
和export
又涉及到打包构建的问题(后面会提到),所以这里只好选择箭头函数这个例子将就看了。
现在,让我们假设Chrome浏览器不支持箭头函数,那我们来看该如何配置,让Karma自动把es6.js
文件转换成浏览器支持的语法再去调用浏览器。首先,安装下面的包
$ yarn add karma-babel-preprocessor
$ yarn add babel-preset-env
创建.babelrc
,配置babel的预转换格式,
.babelrc
{
"presets": ["env"]
}
修改karma.conf.js
,编辑preprocessors
部分,让所有的js文件都先用babel转换一下。
preprocessors: {
"test/*.js": ['babel']
},
配置好之后,我们再用浏览器里查看运行的es6.js
文件,可以看到箭头函数已经转换成了ES5的写法
集成webpack
现在,让我们看看下面的测试用例,引入了第三方库lodash
test/use_lodash.js
import _ from 'lodash'
describe('Use lodash suite', function() {
it('fill array', function() {
var array = [1, 2, 3]
_.fill(array, 'a')
console.log(array)
});
});
运行该测试用例
$ karma run -- --grep 'lodash'
Chrome 57.0.2987 (Mac OS X 10.12.4) ERROR
Uncaught ReferenceError: require is not defined
at test/use_lodash.js:3
查看浏览器运行的use_lodash.js
文件,我们可以看到它被转换成了
'use strict';
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
describe('Use lodash suite', function () {
it('fill array', function () {
var array = [1, 2, 3];
_lodash2.default.fill(array, 'a');
console.log(array);
});
});
虽然已经转换成了ES5语法,但是由于引入了第三方库lodash
,浏览器是没法识别require
指令的。
因此我们需要使用打包工具webpack
来将第三库一起打包出来,让浏览器可以运行。关于webpack的使用,可以参考我之前写的《webpack使用入门》。
这里主要讲怎么让karma使用webpack,首先我们需要安装
$ yarn add webpack
$ yarn add karma-webpack
然后,修改karma.conf.js
, 同样修改preprocessors
部分,添加webpack
到
preprocessors: {
"test/*.js": ['babel', 'webpack']
},
运行
$ karma run -- --grep 'lodash'
LOG: ['a', 'a', 'a']
Chrome 57.0.2987 (Mac OS X 10.12.4): Executed 1 of 1 SUCCESS (0.01 secs / 0.002 secs)
配置webpack
我们也可以对webpack进行配置,如我们前面对Karma调用babel
的功能,也完全可以在webpack里面配置,交给webpack来处理。只需要在karma.conf.js
添加webpack
选项即可进行配置。详情可以参考Karma webpack。
更多关于Karma的配置,可以参考
网友评论