Mocha中文指南

mocha是一款比较流行的测试框架,出自TJ之手,跟jasmine相比,它有灵活的断言语法,测试提示也比较友好,其它方面跟jasmine类似.

使用条件

  • npm install -g mocha
  • mocha *.js

mochajasmine一个显著区别在于,它的断言库不是固定的,支持nodejs自带的assert库,should.js,expect.js,chai,better-assert,然后也支持BDD语法的describeit.

因为should.js也是TJ写的,所以这里重点介绍它的断言语法,更多它的API使用文档,可以点击这里

should.js

下面重点介绍它的一些常用手法,测试环境可以使用mocha

先说下,should.js的一个特点,就是它支持友好语法的链式调用,这些语法其实什么都没做,只是编写比较友好,方便阅读,常见的语法有下面这些

be,an,of,a,and,have,with,is,which,the,在should后面加上not代表相反的意思.

结合比较操作方法,看看下面一个简单的例子

require('should');

describe('test should.js', function(){
    it('test chain', function(){
        (10).should.is.be.the.eql(10);
    });
});

上面例子中的is,be,the其实没有顺序要求,读起来怎么友好就怎么写,因为它们什么都没做,只是返回should.js包装函数.

ok

检查期望的值能否转换成`true`
(true).should.be.ok;

true | True

检查期望的值是否为`true`,不转换
(true).should.be.true;
false.should.not.be.True;

false | False

检查期望的值是否为`false`,不转换
(true).should.not.be.false;
false.should.be.False;

eql

检查期望的值跟真实的值在字面上是否相等,并且深度比较
require('should');

describe('test should.js', function(){
    var foo = {
        foo: 'foo',
        bar: {
            bar: 'bar'
        }
    };
    it('test eql', function(){
        (foo).should.be.eql({
            foo: 'foo',
            bar: {
                bar: 'bar'
            }
        });
    });
});

equal | exactly

检查期望的值与真实的值是一样的,当是比较值类型的话,跟`eql`一样,比较引用类型的话,
则要检查两者是否引用同一地址.
require('should');

describe('test should.js', function(){
    var foo = {
        foo: 'foo',
        bar: {
            bar: 'bar'
        }
    };
    it('test eql', function(){
        (foo).should.not.be.equal({
            foo: 'foo',
            bar: {
                bar: 'bar'
            }
        });
    });
});

throw | throwError

检查期望的函数是否会返回异常,方法参数支持异常信息,正则表达式,对象,以便精确匹配错误信息
(function(){ throw new Error('fail') }).should.throw();
(function(){ throw new Error('fail') }).should.throw('fail');
(function(){ throw new Error('fail') }).should.throw(/fail/);

(function(){ throw new Error('fail') }).should.throw(Error);
var error = new Error();
error.a = 10;
(function(){ throw error; }).should.throw(Error, { a: 10 });
(function(){ throw error; }).should.throw({ a: 10 });

match

检查期望的值与传入的`正则`,`函数`,`对象`进行匹配

匹配规则如下:

  • 如果参数是正则并且期望值是字符串的话,则直接正则匹配字符串即可.
  • 如果参数是正则并且期望值是数组的话,则依次用正则匹配数组元素.
  • 如果参数是正则并且期望值是对象,则依次对对象键值用正则匹配.
  • 如果参数是函数,当函数抛异常或者返回false,则判定为没匹配上.
  • 如果参数是对象,则相同键值用上面的规则来匹配.
  • 其它情况都适为没匹配上.

'foobar'.should.match(/^foo/);
'foobar'.should.not.match(/^bar/);

({ a: 'foo', c: 'barfoo' }).should.match(/foo$/);

['a', 'b', 'c'].should.match(/[a-z]/);

(5).should.not.match(function(n) {
  return n < 0;
});
(5).should.not.match(function(it) {
   it.should.be.an.Array;
});
({ a: 10, b: 'abc', c: { d: 10 }, d: 0 }).should
.match({ a: 10, b: /c$/, c: function(it) {
   return it.should.have.property('d', 10);
}});

[10, 'abc', { d: 10 }, 0].should
.match({ '0': 10, '1': /c$/, '2': function(it) {
   return it.should.have.property('d', 10);
}});

matchEach

依次对期望值进行匹配

匹配规则如下:

  • 如果参数是正则,则依次对期望值中的对象值或者数组项进行正则匹配
  • 如果参数是函数,当函数抛异常或者返回false,则没匹配上
  • 其它情况,则直接按eql来处理

[ 'a', 'b', 'c'].should.matchEach(/\w+/);
[ 'a', 'a', 'a'].should.matchEach('a');

[ 'a', 'a', 'a'].should.matchEach(function(value) { value.should.be.eql('a') });

{ a: 'a', b: 'a', c: 'a' }.should.matchEach(function(value) { value.should.be.eql('a') });

Infinity

检查期望的值是否为无穷大或者无穷小
(10).should.not.be.Infinity;
NaN.should.not.be.Infinity;

NaN

检查期望的值是否为NaN
(10).should.not.be.NaN;
NaN.should.be.NaN;

above | greaterThan

检查期望的值是否大于某数
(10).should.be.above(0);
(10).should.not.be.greaterThan(100);

approximately

检查期望的值大约在(某个数±某个半径)内.
// 9.99 10±0.1
(9.99).should.be.approximately(10, 0.1);

below | lessThan

检查期望的值小于某数
(0).should.be.below(10);
(100).should.not.be.lessThan(10);

within

检查期望的值在某两个数之前,包含两个数
(10).should.be.within(10, 20);
(13).should.be.within(10, 15);

empty

检查期望的值是否为空,比如空字符串,空数组,空对象.
''.should.be.empty;
[].should.be.empty;
({}).should.be.empty;

enumerable

检查期望的值是否有可枚举的属性
({ a: 10 }).should.have.enumerable('a');

enumerables

检查期望的值是否有多个可枚举的属性
({ a: 10, b: 10 }).should.have.enumerables('a', 'b');
({ a: 10, b: 10 }).should.have.enumerables(['a', 'b']);

keys | key

检查期望的值是否包含传入的键
({ a: 10 }).should.have.keys('a');
({ a: 10, b: 20 }).should.have.keys('a', 'b');
({ a: 10, b: 20 }).should.have.keys([ 'a', 'b' ]);
({}).should.have.keys();

length | lengthOf

检查期望的值的长度
[1, 2].should.have.length(2);

ownProperty

检查期望的值是否有自己的某个属性
({ a: 10 }).should.have.ownProperty('a');

properties

检查期望的值是否有某些属性,可以批量检查属性
({ a: 10 }).should.have.properties('a');
({ a: 10, b: 20 }).should.have.properties([ 'a' ]);
({ a: 10, b: 20 }).should.have.properties({ b: 20 });

property

检查期望的值是否有某个属性,单个检查
({ a: 10 }).should.have.property('a');
({ a: 10 }).should.have.property('a', 10);

propertyByPath

根据传入的参数深度来获取属性的值
({ a: {b: 10}}).should.have.propertyByPath('a', 'b').eql(10);

propertyWithDescriptor

检查期望的值的属性有某些描述
({ a: 10 }).should.have.propertyWithDescriptor('a', { enumerable: true });

startWith

检查字符串是否以某个传入的参数开头
'abc'.should.startWith('a');

endWith

检查字符串是否以某个传入的参数结尾
'abc'.should.endWith('c');

instanceof | instanceOf

检查期望的值是否是某个类的实例
'abc'.should.be.instanceof(String);

type

检查期望的值是否是某个类型
'abc'.should.be.type('string');

null | Null

检查期望的值是否为null
var should = require('should');
describe('test should.js ', function(){
    it('test null ', function(){
        should(null).be.null;
    });
});

undefined | Undefined

检查期望的值是否undefined
var should = require('should');
describe('test should.js ', function(){
    it('test undefined', function(){
        var a;
        should(a).be.undefined;
    });
});

上面是一些常用的should.js中的断言方法,下面简单的说下mocha测试框架的用法

异步处理与前后注入

jasmine类似,也是通过在it,beforeEach里传入done来确定是否执行完成

describe('test should.js', function(){

    var foo = 0;

    before('首次调用',function(done){
        setTimeout(function(){
            foo += 1;
            done()
        }, 1000);
    });
    beforeEach(function(done){
        setTimeout(function(){
            foo += 1;
            done();
        }, 1000);
    })
    afterEach(function(){
        foo = 0;
    });
    it('test beforeEach', function(done){
        setTimeout(function(){
            (foo).should.eql(2);
            done();
        }, 1000);
    })

});

禁用与开启测试

  • .only可以让某个it执行而忽略别的it

describe('1.test mocha', function(){

    it.only('test .only', function(){
        '123'.should.be.String;
    });

    // 下面的spec不会执行
    it('ignore invoke', function(){
        (0).should.be.eql(0);
    });
});
  • .skip可以禁止某个it而执行别的it

describe('test mocha', function(){

    // 下面的spec不会执行
    it.skip('ignore spec', function(){
        ({}).should.be.Object;
    });

    it('test .skip', function(){
        ({}).should.be.empty;
    });

});

自由切换bdd,tdd,exports模式

mocha -u [bdd | tdd | exports] *.js

-u选项支持传递要使用的测试类型,默认是bdd,可以选择tdd,exports

BDD

bdd用的比较多,jasmine的测试风格就是bdd,它的特征就是使用describe,it

describe('Array', function(){
  before(function(){
    // ...
  });

  describe('#indexOf()', function(){
    it('should return -1 when not present', function(){
      [1,2,3].indexOf(4).should.equal(-1);
    });
  });
});

TDD

tddbdd区别在于,它使用suite,test,suiteSetup,suiteTeardown,setup,teardown

suite('Array', function(){
      setup(function(){
            // ...
      });

      suite('#indexOf()', function(){
            test('should return -1 when not present', function(){
                ([1,2,3].indexOf(4)).should.be.eql(-1);
            });
      });
});

Exports

exports类似于node里的模块语法,before, after, beforeEach, and afterEach是作为对象的属性来处理,其它对象的值默认是suite,属性是函数的话,代表是一个test

module.exports = {
      before: function(){
            // ...
      },

      'Array': {
            '#indexOf()': {
              'should return -1 when not present': function(){
                [1,2,3].indexOf(4).should.equal(-1);
              }
            }
      }
};

其实的测试风格还有QUnit,Require,更多详情请点击这里.

自由切换输出风格

目前默认的输出格式为spec,可以通用-R spec来指定,目前已有的格式有dot,nyan,tap,list,progress,json,min,doc,markdown等,html格式只在浏览器中有效

mocha细节问题

  • 设置测试组超时时间,可以在describe或者suite代码块里调用this.timeout方法

describe('a suite of tests', function(){
    this.timeout(500);

    it('should take less than 500ms', function(done){
        setTimeout(done, 300);
    })

    it('should take less than 500ms as well', function(done){
        setTimeout(done, 200);
    })
})
  • 设置测试用例超时时间,可以在it或者test代码块里调用this.timeout方法

it('should take less than 500ms', function(done){
  this.timeout(500);
  setTimeout(done, 300);
})
  • mocha默认会执行./test/*.js里的测试文件,所以这个目录是放测试文件的好地方
  • 为了方便执行mocha命令,可以建立一个makefile文件,如下

test:
    ./node_modules/.bin/mocha --reporter list

.PHONY: test

下次运行的话,直接在终端上输入make test

总结

mocha是一个功能比较丰富的测试框架,希望更多的前端工作者们能用上它.

时间: 2016-05-27
Tags: javascript

Mocha中文指南的相关文章

Jasmine中文指南

jasmine是一款非常流行的测试框架,不依赖任何别的库,语法简单,本文是2.1版本的api中文指南. 运行条件 npm install -g jasmine jasmine JASMINE_CONFIG_PATH=jasmine.json jasmine.json配置文件可以随意命名,内容格式如下 { "spec_dir": "jasminetest", "spec_files": [ "*.js" ] } spec_dir

Day01 - JavaScript Drum Kit 中文指南

Day01 - JavaScript Drum Kit 中文指南 作者:liyuechun简介:JavaScript30 是 Wes Bos 推出的一个 30 天挑战.项目免费提供了 30 个视频教程.30 个挑战的起始文档和 30 个挑战解决方案源代码.目的是帮助人们用纯 JavaScript 来写东西,不借助框架和库,也不使用编译器和引用.现在你看到的是这系列指南的第 1 篇.完整指南在 从零到壹全栈部落. 简介 第一天的练习是用JS制作一个爵士鼓的页面,通过敲击键盘上不同的字母,会发出不同

Day05 - Flex 实现可伸缩的图片墙 中文指南

Day05 - Flex 实现可伸缩的图片墙 中文指南 作者:liyuechun简介:JavaScript30 是 Wes Bos 推出的一个 30 天挑战.项目免费提供了 30 个视频教程.30 个挑战的起始文档和 30 个挑战解决方案源代码.目的是帮助人们用纯 JavaScript 来写东西,不借助框架和库,也不使用编译器和引用.现在你看到的是这系列指南的第 5 篇.完整指南在 从零到壹全栈部落. 实现效果 点击任意一张图片,图片展开,同时从图片上下两方分别移入文字.点击已经展开的图片后,图

Day07 - Array Cardio 中文指南二

Day07 - Array Cardio 中文指南二 作者:liyuechun简介:JavaScript30 是 Wes Bos 推出的一个 30 天挑战.项目免费提供了 30 个视频教程.30 个挑战的起始文档和 30 个挑战解决方案源代码.目的是帮助人们用纯 JavaScript 来写东西,不借助框架和库,也不使用编译器和引用.现在你看到的是这系列指南的第 7 篇.完整中文版指南及视频教程在 从零到壹全栈部落. 第七天的练习是接着之前Day04 - Array Cardio 中文指南一的练习

开源图书 —— 《Docker中文指南》

Docker中文指南 详细介绍docker正式版已经推出,做的改动非常多,以前版本的docker翻译已经不能用了,所以现在重新开始希望有兴趣的朋友一起加入! About the author Questions and Issues Edit and Contribute Introduction 安装篇 1.1. Mac OS X 1.2. Ubuntu 1.3. Red Hat Enterprise Linux 1.4. CentOS 1.5. Debain 1.6. Gentoo 1.7.

英国主机商Host1Plus推出中文站进军中国市场

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 近日,英国主机商Host1Plus于日前正式推出中文官方网站http://cn.Host1Plus.com,Host1Plus中文站的推出也是其进军中国市场的一个强有力的信号,这也是继五月份Webhostingpad推出中文网站http://cn.webhostingpad.com之后,又一家入驻中国虚拟主机市场的国外主机商. Host1p

看懂前端脚手架你需要这篇WEBPACK

本文转载自网络.转载编辑过程中,可能有遗漏或错误,请以原文为准. 原文作者:二口南洋 原文链接: https://gold.xitu.io/post/586ddb8ab123db005d0b65cb Webpack 是当下最热门的前端资源模块化管理和打包工具.它可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源.还可以将按需加载的模块进行代码分隔,等到实际需要的时候再异步加载.通过loader 的转换,任何形式的资源都可以视作模块,比如 CommonJs 模块. AMD 模块.

Python资源大全

The Python Tutorial (Python 2.7.11) 的中文翻译版本.Python Tutorial 为初学 Python 必备官方教程,本教程适用于 Python 2.7.X 系列. 在线阅读 » Fork Me » The Python Tutorial (Python 3.5.1) 的中文翻译版本.Python Tutorial 为初学 Python 必备官方教程,本教程适用于 Python 3.5.x. 在线阅读 » Fork Me » Flask 是一个轻量级的 We

前端知识库

前端开发全面知识库,包括HTML5,CSS3和js的基本框架知识,以及DOM和BOM操作的基础知识和一些基本工具和IDE.学习本篇,你将了解到以下知识. 核心 Core HTML5 W3C http://www.w3school.com.cn/html5/ W3C https://www.w3.org/html/ig/zh/wiki/HTML5 菜鸟教程 http://www.runoob.com/html/html5-intro.html HTML5中文门户 http://www.html5c