前端单元测试-mocha

486 阅读4分钟

什么是单元测试?

单元测试是指对一个模块、一个函数或者一个类来进行正确性检验的测试工作

为什么需要单元测试?

  • 保证质量:随着迭代的过程,开发人员很难记清所有的功能点,功能点的新增和删除在代码改变后,进行回归测试时,依靠人工QA很容易出错遗漏。
  • 自动化:通过编写测试用例,只需要编写一次,多次运行,同样的事情不需要从头再来测一遍,很多时候QA的工作量就是这么增加的,新的版本上线,人工QA都需要所有的功能点从新测试一遍。
  • 特性文档:单元测试可以作为描述和记录代码所实现的所有需求,有时候可以作为文档来使用,了解一个项目可以通过阅读测试用例比看需求文档更清晰。
  • 驱动开发,指导设计:代码被测试的前提是代码本身的可测试性,那么要保证代码的可测试性,就需要在开发中注意API的设计,TDD将测试前移就是起到这么一个作用

TDD vs BDD

Test Driven Development (TDD) 测试驱动开发

  • TDD 的原理就是在编写代码之前先编写测试用例,由测试来决定我们的代码,而且 TDD 更多的需要编写独立的测试用例,比如只测试一个组件的某个功能点,某个工具函数等。它是白盒测试
  • 开发流程大致是:编写测试用例、运行测试、编写代码使测试通过、优化代码。 TDD 的优势:从长期来看,可以有效减少回归测试的 Bug;因为先编写测试,所以可能出现的问题都被提前发现了;测试覆盖率高,因为后编写代码,因此测试用例基本都能照顾到;保证代码质量。
  • TDD 的劣势:因为侧重点在于代码,更多是保证某个测试单元没问题,因此无法保证业务流程没有问题;而且需求经常变更,在修改某个功能点之前要先修改测试用例,因此在复杂的项目中工作量很大;测试代码和实际代码可能会出现耦合,经常需要修改。

BDD (Behavior Driven Development) 行为驱动开发

  • BDD 是从产品角度出发,它鼓励开发人员和非开发人员之间的协作,是一种黑盒测试。 开发流程大致是:获悉需求并编写代码,然后再从用户角度编写集成测试。
  • BDD 的优势:它的测试重点更多是站在项目角度,在 UI 和 DOM 的角度进行测试,直接地测试业务流程是否没问题,测试代码和实际代码解耦。
  • BDD 的劣势:因为是集成测试,因此不是那么关注每个函数功能,测试覆盖率比较低,没有 TDD 那么严格的保证代码质量。

测试框架/工具选择

  • Mocha
  • Jasmine
  • Jest
  • Karma

这里我们选Mocha

实现原理

测试框架:判断内部是否存在异常,存在则console出对应的text信息

断言库:当实际值与期望值不一样时,就抛出异常,供外部测试框架检测到,这就是为什么有些测试框架可以自由选择断言库的原因,只要可以抛出异常,外部测试框架就可以工作

断言库

  • Chai
  • Jasmine
  • Jest
  • Unexpected

开始

mkdir unit-test-mocha
cd unit-test-mocha
npm init

接下来一顿回车

安装mocha

npm install --save-dev mocha

添加package.json命令

"scripts": {
    "test": "mocha"
 }

添加测试用例

在根目录添加test(mocha默认执行目录)文件夹,如要修改mocha ./spec/*.js,将修改为spec目录

然后在test目录下添加*.js文件,例如a.js

给a.js添加内容

var assert = require('assert');
describe('Array', function() {
  describe('#indexOf()', function() {
    it('should return -1 when the value is not present', function() {
      assert.equal([1,2,3].indexOf(4), -1);
    });
  });
});

这里是直接使用的node的断言模块assert,推荐使用chai断言库,因为语法更接近自然语言。

安装chai

npm install --save-dev chai

chai支持三种不同的风格写法,这里使用expect风格,与assert语法对比:

const { expect } = require('chai')
describe('Array', function() {
  describe('#indexOf()', function() {
    it('should return -1 when the value is not present', function() {
      expect([1,2,3].indexOf(4)).to.equal(-1)
    });
  });
});

运行

npm run test 或者 ./node_modules/mocha/bin/mocha

测试报告输出

有三种风格

  • 默认mocha --reporter spec(mocha === mocha --reporter spec)
  • mocha --reporter tap
  • mocha --reporter mochawesome(需要使用mochawesome模块,可以生成HTML格式报告)

安装mochawesome

npm install --save-dev mochawesome

修改package.json:

"scripts": {
    "test": "mocha --reporter mochawesome"
 }

然后执行npm run test,会在当前工程mochawesome-report目录下生成mochawesome.html报告文件。如下:

异步处理

done回调 or promise

修改默认超时时间

默认的超时时间是2000ms,修改方式:

1. mocha --timeout 5000
2. 在顶级 describe 中调用this.timeout(5000)

部分执行

it.only
it.skip

tips

mocha默认只获取test/*.js测试用例,如何有更深层级,需添加--recursive运行参数,修改package.json:

"scripts": {
    "test": "mocha --recursive --reporter mochawesome"
 }

浏览器中运行

详情见官方文档

配合vue使用

...