js测试框架:mocha学习总结

一、总结

教程引用自:阮大神的文章

1.1 Mocha

  • 是现在最流行的JavaScript测试框架之一,在浏览器和Node环境都可以使用。
  • 所谓”测试框架”,就是运行测试的工具。通过它,可以为JavaScript应用添加测试,从而保证代码的质量。
  • 除了Mocha以外,类似的测试框架还有Jasmine、Karma、Tape等,也很值得学习。
# 安装
npm install mocha -g  
npm install mocha --save

1.1.1 写测试脚本

mocha的作用就是运行测试脚本(用来测试源码的脚本)。
例:测试一个加法模块add.js的测试脚本add.test.js

# add.js 模块
function add(x,y){return x+y;}
module.exports = add;

# add.test.js 测试脚本
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 add.test.js
  1. 通常测试脚本与被测试 的源码脚本同名,但后缀名为.test.js(表示测试)或.spec.js(表示规格)
  2. describe 块:被称为测试套件,表示一组相关的测试。它是一个函数,参数1为测试套件名,参数2为实际执行函数。(测试脚本里应该包括一个或多个describe块)
  3. it块:测试用命 test case,表示一个单独的测试单元,它也是一个函数,参数1为测试用例名称,参数2为实际执行的函数(每个describe块中应该包括一个或多个it块)
  4. expect:断言,就是判断源码的实际执行结果与预期结果是否一致,如果不一致就抛出一个错误。(所有测试用命(it块)都应该含有一句或多名断言。)(断言功能由断言库来实现,mocha本身不带断言库,所以必须先引入断言库,如本例中的chai

1.1.2 expect的语法


// 相等或不相等
expect(4 + 5).to.be.equal(9);
expect(4 + 5).to.be.not.equal(10);
expect(foo).to.be.deep.equal({ bar: 'baz' });

// 布尔值为true
expect('everthing').to.be.ok;
expect(false).to.not.be.ok;

// typeof
expect('test').to.be.a('string');
expect({ foo: 'bar' }).to.be.an('object');
expect(foo).to.be.an.instanceof(Foo);

// include
expect([1,2,3]).to.include(2);
expect('foobar').to.contain('foo');
expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');

// empty
expect([]).to.be.empty;
expect('').to.be.empty;
expect({}).to.be.empty;

// match
expect('foobar').to.match(/^foo/);

二、Mocha的用法总结

# 测试指定脚本
$ mocha file1.test.js 

# 测试整个文件中的脚本(只对test文件夹有效)
$ cd test
$ mocha

# 测试test目录下的所有文件(包括子文件夹)
$ cd test 
$ mocha --rescursive

# 指定执行多个文件
$ mocha spec/{my,awesome}.js   // 指定spec目录下的my,asesome
$ mocha test/unit/*.js  // 指定test/unit下的所有js
  • mocha默认运行test子目录里的测试脚本。所以,通常把测试脚本放在test目录里,然后执行mocha就不需要参数了
  • --recursive递归执行

2.1 mocha命令行参数

# --help 或 -h  帮助
$ mocha -h
# 指定测试报告格式,默认是spec格式
mocha --reporter spec
# 桌面显示测试结果
$ mocha --growl
# 监视指定测试的脚本,自动运行mocha
$ mocha --watch
# 指定只要有一个测试用例没通过,就停止执行后面的测试用例
$ mocha --bail
# 搜索指定用例并执行
$ mocha --grep "1加1"


  • 使用mochawesome模块,可以生成漂亮的HTML格式的报告

细节补充
HTML格式的测试报告:mochawesome

$ npm install --save-dev mochawesome
$ mocha testfile.js --reporter mochawesome
  • 以上示例用的awesome版本为:~1.2.1,mocha版本~2.3.4

2.2 配置文件mocha.opts

Mocha允许在test目录下面,放置配置文件mocha.opts,把命令行参数写在里面。

# 目录结构
|_ test
    |_ dir
        |_ add.test.js
    |_ dec.test.js
    |_ mocha.opts

# 编写mocha配置
--reporter tap
--recursive
# 运行
$ mocha

2.3 生成规格文件

# 生成markdown格式的规格文件
$ mocha --recursive -R markdown > spec.md
# 生成html报告
$ mocha --recursive -R doc > spec.html

三、ES6测试

如果测试脚本是用ES6写的,那么运行测试之前,需要先用Babel转码。

# 安装babel
$ npm install babel-core babel-preset-es2015 --save-dev
# 配置.babelrc
{
    "presets":["es2015"]
}
# 编译配置 mocha.opts
--compilers js:babel-core/register
# 运行
$ mocha
  • 以上--compilers参数后 跟的 js:babel-core/register,冒号左边是文件的后缀,右边是用来处理这类文件的模块名。
  • 以上代码表示,运行测试前,先用babel-core/register模块,处理一下.js文件。
  • 注意:babel默认不会对Iterator,Generator,Promise,Map,Set等全局对象,以及一些全局对象的方法(如Object.assign)转码,如果想要对这些对象转码,bable-polyfill
$ npm install babel-polyfill --save
# 在脚本头部加一行
import 'babel-polyfill'

四、异步测试

Mocha默认每个测试用例最多执行2000毫秒,如果到时没有得到结果,就报错。对于涉及异步操作的测试用例,这个时间往往是不够的,需要用-t--timeout参数指定超时门槛。

# 异步请求测试用例
it('异步请求应该返回一个对象', function(done){
  request
    .get('https://api.github.com')
    .end(function(err, res){
      expect(res).to.be.an('object');
      done(); //需要显示调用done,告知测试结束
    });
});
# 配置 -t ,设置超时时间
$ mocha -t 10000 async.test.js

# mocha内置对Promise的支持,等它状态改变,再执行断言,而不用显示调用done方法
it('异步请求应该返回一个对象', function() {
  return fetch('https://api.github.com')
    .then(function(res) {
      return res.json();
    }).then(function(json) {
      expect(json).to.be.an('object');
    });
});

五、测试用例的钩子

Mocha在describe块之中,提供测试用例的四个钩子:before()、after()、beforeEach()afterEach()。它们会在指定时间执行。


describe('hooks', function() {

  before(function() {
    // 在本区块的所有测试用例之前执行
  });

  after(function() {
    // 在本区块的所有测试用例之后执行
  });

  beforeEach(function() {
    // 在本区块的每个测试用例之前执行
  });

  afterEach(function() {
    // 在本区块的每个测试用例之后执行
  });

  // test cases
});
发布了114 篇原创文章 · 获赞 146 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/Sophie_U/article/details/80021077