mocha介绍
mocha作为最流行的JavaScript测试框架之一,可以用于测试node.js服务和运行在浏览器环境下的js代码。
Mocha is a feature-rich JavaScript test framework running on Node.js and in the browser, making asynchronous testing simple and fun.
官方给它自己定义的三个特点是simple、flexible、fun。
flexible是因为mocha本身不包含断言库、mock等功能,用户可以根据自己的需要灵活地选择所需要的额外功能。
单元测试流程
编写单元测试代码的流程基本就是 梳理代码流程 -> 针对每一个分支编写单元测试 -> 运行单测代码 -> 查看测试覆盖率报告。
mocha本身十分简单,只要执行 mocha
命令就会默认运行test
子目录下的测试脚本。但这样简单的功能并不能满足我们的需求,我们需要引入一些npm包来加强一下。
nyc
nyc用于统计我们的单测代码测试覆盖率,使用起来也很简单:在测试脚本前加上nyc即可。
{ "scripts": { "test": "mocha", "coverage": "nyc npm run test" } }复制代码
babel
使用babel可以让我们使用es6的语法编写单测代码。
首先我们需要安装babel包: npm i -D @babel/cli @babel/core @babel/preset-env @babel/register
然后添加babel配置文件:
// .babelrc.js{ "presets": ["@babel/preset-env"] }复制代码
然后给mocha命令添加参数,指定使用babel进行编译: mocha --require @babel/register
如果觉得命令行参数太多太长,mocha允许我们使用配置文件的方式来进行传参:
module.exports = { require: ["@babel/polyfill", "@babel/register"], // 运行单测代码时需要使用babel解析 recursive: true, // 深度遍历指定目录 spec: 'test/**/*.test.js', // 运行test目录下的所有单测代码}复制代码
编写单测
完成mocha的插件配置和环境搭建后,终于到了写代码环节了。其实个人觉得单元测试中最重要的环节应该是梳理业务流程,如果能把业务流程梳理为清晰的流程图,写起单测来也会事半功倍。
在编写代码前我们需要来了解下mocha的运行规则,下面是一份测试加法运算函数的单测代码:
import getResult from 'add.js'import { assert } from 'chai'describe('测试getResult函数', function() { it ('正常入参', function() { const res = getResult(123); assert(res != null, '函数正常入参执行错误') }) it ('非法入参', function() { const res = getResult(); assert(res == null, '函数非法入参执行错误') }) })复制代码
每一份单元测试脚本都应该至少包含一个describe
模块,describe
定义了一组逻辑相关的测试组,第一个入参是测试组的名称,第二个入参是交给mocha框架执行的函数。函数内会包含由it
定义的测试用例,用来测试该测试组的不同分支。
完整的单测至少应该包含正反方向
测试,即测试函数的正常逻辑和异常逻辑。可以看到上述代码定义了一个describe组来测试getResult函数的功能,里面有两个测试用例分别测试了入参正常和非法入参的情况。
而测试用例中如何来判断函数是否正常执行呢?这时候就要用到断言
了。
chai断言库
mocha可以搭配你喜欢的任何断言库,经常使用到的有chai
断言库。
chai提供了多种风格语法去帮助我们判断函数的执行结果。上述例子中用的是assert语法,它是基于node的assert模块进行扩展。
简单来说,断言库就是帮助我们去判断某些变量是否符合我们的要求,并且在不符合时做出错误提示。
举个:chestnut::
assert(res != null, '函数正常入参执行错误')复制代码
就是判断res是否不等于null。当第一个入参的表达式结果为false时,表示不符合预期,这是测试用例不通过,会打印出第二个入参的提示语。
异步逻辑
上述的单测例子里,被测试的函数只有同步逻辑,而在js中,异步逻辑无处不在。那么对于异步逻辑需要怎么测试呢?
mocha提供了两种方法来解决这个问题:
promise
我们可以返回一个promise给mocha框架,等到promise的状态改变时再执行断言:
it('测试异步函数', function() { return fetch('url') .then((res) => { assert.isObject(res.json(), 'res should be an object'); }) })复制代码
显示返回done
it方法的第二个入参是一个执行函数,我们可以给这个函数传入一个done方法,等到异步返回后再去显示地调用done方法,告诉mocha该测试用例执行完毕。
it('测试异步函数', function(done) { fetch('url') .then((res) => { assert.isObject(res.json(), 'res should be an object'); done(); }) })复制代码
另外需要注意的是,mocha默认每个测试用例的超时时间为2000毫秒,如果超时就会报错。当我们的异步逻辑耗时较长时,需要手动地调整这个超时时间。
共同學(xué)習(xí),寫下你的評(píng)論
評(píng)論加載中...
作者其他優(yōu)質(zhì)文章