项目中屡次使用karma + webpack + chai + mocha + sinon作单元测试。配置脚本都是从别人的项目中拷贝来的,对其中部分库是干什么的,以及这些库之间是如何融合在一块儿工做的具体机制都是只知其一;不知其二。本文探索karma如何与测试框架合做, 但愿能深刻一点(本文记录我的学习的过程,或有谬误,请多指教。)html
咱们从最原始的js测试出发,假设我写了2个函数:前端
// 待测试的代码 function add(x, y) { return x + y } function sub(x, y) { return x - y + 1 // 很明显这个函数写错了 }
咱们如今想测试他们,怎么测试呢?webpack
咱们给待测试的函数设置了一些输入,而后咱们观察他们是否能给出正确的输出。git
// 测试用例 var testCase1 = function() { var sum = add(1, 3) if (sum === 4) { console.log('OK') } else { console.log('Error') } } var testCase2 = function() { var sum = sub(5, 2) if (sum === 3) { console.log('OK') } else { console.log('error') } }
而后咱们能够写一个html页面,加载待测试函数和测试用例,在添加上这2行运行测试用例的代码:github
// 测试执行 testCase1() testCase2()
最后在网页console咱们观察结果:web
好的,咱们发现咱们的sub
函数写错了。npm
这彷佛很蠢,而后确实就是一个测试的过程,固然这个过程并不能用于工程,它有有不少问题:浏览器
这些问题均可以经过咱们上面提到的karma工具链来解决。框架
这玩意是什么?官方说法: a test runner
。那又是什么? 能不能说人话?按我我的理解,Test runner的主要功能就是执行测试用例并输出测试结果的一个库,也就是说Karma至少解决了上面提到问题里的1,2和3。
用过karma的人都知道: 经过安装一些库,作一些配置,karma就能与不少测试框架协做从而能让咱们经过一条命令直接完成测试的执行和结果输出,那么Karma若是作到的呢?函数
咱们改造一下上面实例的代码,建立一个前端项目:
内容很简单:
// src/index.js // src里是源码 function add(x, y) { return x + y } function sub(x, y) { return x - y + 1 }
// test/index.js // 测试用例代码写在这里, window.__karma__相关的代码先忽略 var testCase1 = function() { var sum = add(1, 3) if (sum === 4) { window.__karma__.result({ id: 1, description: '1 + 3 = 4', suite: ['leon'], log: ['OK'], success: true, skipped: false }) } else { console.log('Error') } } var testCase2 = function() { var sum = sub(5, 2) if (sum === 3) { console.log('Success') } else { window.__karma__.result({ id: 2, description: '5 - 2 = ' + sum, suite: ['leon'], log: ['OK'], success: false, skipped: false }) } } window.__karma__.start = function () { window.__karma__.info({ total: 2 }) testCase1() testCase2() window.__karma__.complete() }
// karma.conf.js module.exports = function(config) { config.set({ .... // list of files / patterns to load in the browser files: [ 'src/index.js', 'test/index.js' ], ... }) }
如今咱们的工程结构清晰了.
src
下是源码test
下是测试用例karma.conf.js
里是测试配置(咱们使用最简单的设置,基本就只指定了一个要加载的文件)咱们执行一下测试(npm run test
)看看结果:
karma start karma.conf.js --log-level debug
2个测试用例都被执行了,结果也清晰的打印在了console上了。
咱们经过命令(npm run tdd)把测试网页跑起来, 而后打开测试的页面http://localhost:9876/debug.html
能够看到
原来每次咱们执行Karma start命令的时候,Karma就是自动把咱们在karma.conf.js
的files
字段里的文件都加载到网页里了。
实际上File 字段的注释已经说得很清楚了: list of files / patterns to load in the browser
Karma如何知道测试的开始,结束,每条用例的结果的呢?Karma的文档里说得也很清楚(可是彷佛不太准确)
上面贴test/index.js
代码的时候我就提到了,window.__karma__
相关的代码先忽略。实际上这个是karma给测试用例或者更高级一点的测试框架的通讯接口:
从上面的例子中,能够很明显的体会到这些功能:
咱们实现一个window.__karma__.start函数,以便Karma框架能够调用,在这个函数里咱们首先告诉Karma咱们一共有2个测试用例,而后咱们再去执行这2个测试用例,最后通知karma测试结束了。在测试用例里,咱们再也不简单的使用cossole.log来打印结果,而是用window.__karma__.result
把详细的结果通知给Karma
// Karma框架调用 window.__karma__.start = function () { // 咱们有2个测试用例 window.__karma__.info({ total: 2 }) // 执行用例 testCase1() testCase2() // 通知karma测试结束了 window.__karma__.complete() }
可是以前咱们写测试用例的时候没写过这些__karma__.xxx函数啊!是啊,通常咱们是不会像例子里这样本身写测试用例,本身管理的,而都是用mocha这样的测试框架的。
例子:
var add = require('./add.js'); var expect = require('chai').expect; describe('加法函数的测试', function() { it('1 加 1 应该等于 2', function() { expect(add(1, 1)).to.be.equal(2); }); });
实际上在用mocha
的时候,咱们都是要安装一个库叫karma-mocha. 这个库就是把这些__karma__.xxx的函数都封装了一遍, 因此咱们都只顾着写mocha
的测试用例就好了。
看一眼这个库的说明:Adapter for Mocha testing framework.
原来是这个意思啊!!
不少时候咱们都用一些现成的东西,以致于都不会去深究一些事情的本质,因此在遇到深一点层次的问题的时候都会以为无所适从。有时候事情的本质实际上没那么复杂,咱们只是确少去发掘的勇气和精力。