|
2#
楼主 |
发表于 2018-1-16 16:09:44
|
只看该作者
3.3 集成webpack
很多时候,项目中会用到webpack来进行打包,有了Webpack我们可以使用ES6甚至ES7语法,可以轻松打包Vue、React、Angular等主流框架,可以有Eslint代码检查。所以将Webpack集成进Karma后,我们可以使用最新的JS语法来编写测试代码,也可以对使用了主流框架的代码进行单元测试了。
这里我们以使用ES6语法为目的,来演示如何集成Webpack。
3.3.1 安装Webpack和Babel
首先安装Webpack和karma-webpack插件
- npm install webpack karma-webpack --save-dev
- 然后安装babel
- npm i --save-dev babel-loader babel-core babel-preset-es2015
复制代码
3.3.2 在Karma中配置和使用Webpack
修改karma.conf.js,将webpack添加进去。
3.3.2.1 设置需要Webpack打包的文件
在preprocessors中告诉karma需要Webpack打包的文件所在位置,这里我想同时在被测试代码和测试代码中使用ES6语法,那么理论上我除了将被测试代码位置告诉Webpack之外,还需要将测试代码的位置也告诉Webpack。
但如果你的代码是模块化的,使用了ES6的模块系统,那么即使你将已经模块化的index.js打包并好并注入到浏览器也是没有用的,所以正确的做法应该是在你的测试代码也就是index.test.js中引入index.js模块进行测试。然而Webpack在处理index.test.js时会查找它的引用并自动打包过来,所以如果你的被测试代码是模块化的,Karma配置中的preprocessors中就应当去掉Webpack对被测试代码的处理,同时files中也不需要让Karma将被测试代码放到浏览器了,这一切应当都交给Webpack来做:
- preprocessors: {
- // 'src/*.js': ['webpack', 'coverage'],
- 'src/*.js': ['coverage'],
- 'test/*.js': ['webpack']
- },
- files: [
- // './src/*.js',
- './test/*.js'
- ],
- 3.3.2.2 配置好Webpack
- 在Karma中写好Webpack的配置:
- // webpack config
- webpack: {
- module: {
- loaders: [{
- test: /\\.js$/,
- loader: 'babel',
- exclude: /node_modules/,
- query: {
- presets: ['es2015']
- }
- }]
- }
- },
复制代码
这一步有三点需要注意:
上面这些配置,完全可以独立出来成为一个webpack.test.config.js,怎么样,是不是很眼熟?
你可能已经注意到Webpack的配置中没有entry,也没有output,因为在Karma的preprocessors中已经告诉了Webpack需要打包哪些文件了,同时Karma也会处理好打包后文件的去向(当然是注入浏览器了,还能去哪,别忘记了还有karma-webpack这个插件在起作用)
测试的Webpack配置除了上面说的入口和出口,其余的配置跟普通使用Webpack没有本质区别,所以从这里你完全可以发散思维,用Webpack去做你想做的~
3.3.2.3 添加karma-webpack插件
别忘记新版的Karma几乎所有的工具都需要插件支持,这在老版本中是不需要的。所以得把karma-webpack添加到Karma的plugins中去
- plugins : [
- 'karma-mocha',
- 'karma-chai',
- 'karma-phantomjs-launcher',
- 'karma-coverage',
- 'karma-webpack'
- ],
- 3.3.2.4 在你的被测试代码和测试代码中使用ES6语法
- 首先是被测试代码
- function isNum (num) {
- return typeof num === 'number'
- }
- function isString (str) {
- return typeof str === 'string'
- }
- export default {
- isNum,
- isString
- }
- 然后是测试代码
- import Index from '../src/index'
- console.log('开始测试')
- describe('index.js的测试', function () {
- it('1应该是数字', function() {
- // expect(isNum(1)).to.be.true
- Index.isNum(1).should.equal(true)
- })
- it('"1" 应该是字符', function() {
- // expect(isString('1')).to.be.true
- Index.isString('1').should.equal(true)
- })
- })
复制代码 我这里使用了ES6 中的模块写法,在index.js中输出了一个带有两个方法的模块,这时测试代码中就需要引入这个模块了,因为仅仅是简单地将index.js输出到浏览器是不会起任何作用的(webpack打包后,两个需要测试的函数已经是私有变量了,前文也有所提及)。
这时再运行karma start,便能看到测试通过的结果,说明我们成功使用了webpack编译了ES6。现在检查一下代码覆盖率:
会发现代码覆盖率无法正常检测了。即使你注释掉某个函数的测试用例,代码覆盖率仍旧是100%。这就是前文提到的,如果使用karma-coverage检测Webpack打包后的代码,就会出现这种情况。所以这里我们需要使用其它办法来检测代码覆盖率。
一般代码覆盖率的检测是需要统计被测试代码中需要测试的量,比如函数、行数等信息,然而打包后的代码因为被混入了很多别的代码,或者是变量被私有化了,这些统计就会出问题。所以最好的办法是在打包之前进行统计。
方案其实有很多,比如isparta、isparta-instrumenter-loader、istanbul。这里选择istanbul,因为karma-coverage用的就是它。同时,babel提供了一个插件babel-plugin-istanbul,能够在babel编译之前instrument你的ES6代码,可以像下面这样使用(参考babel-plugin-istanbul):
首先安装babel-plugin-istanbul:
- npm install babel-plugin-istanbul --save-dev
- 然后将其放入到babel的插件选项中:
- loaders: [{
- test: /\\.js$/,
- loader: 'babel',
- exclude: /node_modules/,
- query: {
- presets: ['es2015'],
- plugins: ['istanbul']
- }
- }]
- 这里需要注意的是:
- Note: This plugin does not generate any report or save any data to any file;it only adds instrumenting code to your JavaScript source code.To integrate with testing tools, please see the Integrations section.
- —— cnpm babel-plugin-istanbul
- 这个插件的功能仅仅是instrument,不生成报告,所以报告的生成还是需要karma-coverage来完成的,所以之前有关karma-coverage的设置只需要将instrument部分也就是karma.conf.js中的preprocessors中的coverage去掉即可:
- preprocessors: {
- // 'src/*.js': ['webpack', 'coverage'],
- // 'src/*.js': ['coverage'],
- 'test/*.js': ['webpack']
- },
- 这时再次运行karma start,便能看到测试通过的结果,说明我们成功使用了webpack编译了ES6。现在检查一下代码覆盖率:
复制代码
已经恢复正常了!按照上面的思路,我们完成了将Webpack配置到Karma中的工作,所以现在你可以使用Webpack来统一管理你的被测试代码和测试代码了。
4. 其它注意事项
4.1 关于npm
正常情况下国内是需要翻墙才能使用npm的,但你有两个选择:翻墙或者使用cnpm。我建议使用cnpm,安装使用可以去cnpm官网查看详细教程(非常简单)
4.2 关于测试框架mocha和断言库chai.js
一个咖啡一个茶,虽然你已经能够将它们运用到你的构建体系中去了,但这两者的详细API还是需要去熟悉和了解的,否则也没办法写出高质量的测试代码
mocha除了可以去mocha官方网站看英文文档之外,还可以参考我翻译的中文文档:Mocha.js官方文档翻译 —— 简单、灵活、有趣
chai.js则只需要去chai.js官方网站看API文档,我也翻译了TDD部分的API文档:Chai.js断言库API中文文档
4.3 关于BDD与TDD
BDD是行为驱动开发,TDD是测试驱动开发。但其实可以认为BDD是TDD的一个子集或分支,是测试驱动开发的升级版。具体可以参考这几篇文章:
虚拟座谈会:代码测试比率、测试驱动开发及行为驱动开发
亲身体验行为驱动开发
Mocha既是测试工具,也是测试框架,其实有不少测试工具既是管理工具,也是测试框架 ↩
|
|