Mocha
(发音"摩卡")诞生于2011年,是现在最流行的JavaScript测试框架之一,在浏览器和Node环境都可以使用。
所谓"测试框架",就是运行测试的工具。通过它,可以为JavaScript应用添加测试,从而保证代码的质量。
本文全面介绍如何使用Mocha
,让你轻松上手。如果你以前对测试一无所知,本文也可以当作JavaScript单元测试入门。值得说明的是,除了Mocha以外,类似的测试框架还有Jasmine
、Karma
、Tape
等,也很值得学习。
一、安装
首先安装一个Mocha-demos的库。
如果电脑没有Git,可以直接下载zip压缩包。
github地址:https://github.com/ruanyf/mocha-demos.git
然后进入到mocha-demos目录安装依赖(首先电脑必须有node)。
上述代码会在目录内部安装Mocha,为了操作方便可以在全局环境也安装一下Mocha。
二、测试脚本的写法
Mocha的作用是运行测试脚本,首先需要学会写测试脚本。所谓测试脚本就是用来测试源码的脚本。下边是一个加法模块add.js的代码。
通常,测试脚本与所要测试的源码脚本同名,但是后缀名为.test.js
(表示测试)或者.spec.js
(表示规格)。
比如,add.js
的测试脚本名字就是add.test.js
。
上面这段代码,就是测试脚本,它可以独立执行。测试脚本里面应该包括一个或多个describe
块,每个describe
块应该包括一个或多个it
块。
describe
块称为"测试套件"(test suite),表示一组相关的测试。它是一个函数,第一个参数是测试套件的名称("加法函数的测试"),第二个参数是一个实际执行的函数。
it
块称为"测试用例"(test case),表示一个单独的测试,是测试的最小单位。它也是一个函数,第一个参数是测试用例的名称("1 加 1 应该等于 2"),第二个参数是一个实际执行的函数。
三、断言库的用法
上面的测试脚本里面,有一句断言。
所谓"断言",就是判断源码的实际执行结果与预期结果是否一致,如果不一致就抛出一个错误。上面这句断言的意思是,调用add(1, 1)
,结果应该等于2。
所有的测试用例(it块)都应该含有一句或多句的断言。它是编写测试用例的关键。断言功能由断言库来实现,Mocha本身不带断言库,所以必须先引入断言库。
断言库有很多种,Mocha并不限制使用哪一种。上面代码引入的断言库是chai
,并且指定使用它的expect
断言风格。
expect
断言的优点是很接近自然语言,下面是一些例子。
基本上,expect
断言的写法都是一样的。头部是expect
方法,尾部是断言方法,比如equal
、a
/an
、ok
、match
等。两者之间使用to
或to.be
连接。
如果expect
断言不成立,就会抛出一个错误。事实上,只要不抛出错误,测试用例就算通过。
上面的这个测试用例,内部没有任何代码,由于没有抛出了错误,所以还是会通过。
四、Mocha的基本用法
有了测试脚本以后,就可以用Mocha运行它。请进入demo01
子目录,执行下面的命令。
上面的运行结果表示,测试脚本通过了测试,一共只有1个测试用例,耗时是8毫秒。
mocha
命令后面紧跟测试脚本的路径和文件名,可以指定多个测试脚本。
Mocha默认运行test
子目录里面的测试脚本。所以,一般都会把测试脚本放在test
目录里面,然后执行mocha
就不需要参数了。请进入demo02
子目录,运行下面的命令。
这时可以看到,test
子目录里面的测试脚本执行了。但是,你打开test
子目录,会发现下面还有一个test/dir
子目录,里面还有一个测试脚本multiply.test.js
,并没有得到执行。
原来,Mocha默认只执行test
子目录下面第一层的测试用例,不会执行更下层的用例。
为了改变这种行为,就必须加上--recursive
参数,这时test
子目录下面所有的测试用例----不管在哪一层----都会执行。
五、异步测试
Mocha默认每个测试用例最多执行2000毫秒,如果到时没有得到结果,就报错。对于涉及异步操作的测试用例,这个时间往往是不够的,
需要用-t
或--timeout
参数指定超时门槛。
进入demo05
子目录,打开测试脚本timeout.test.js
。
上面的测试用例,需要4000毫秒之后,才有运行结果。所以,需要用-t
或--timeout
参数,改变默认的超时设置。
上面命令将测试的超时时限指定为5000毫秒。
另外,上面的测试用例里面,有一个done
函数。it
块执行的时候,传入一个done
参数,当测试结束的时候,必须显式调用这个函数,告诉Mocha测试结束了。
否则,Mocha就无法知道,测试是否结束,会一直等到超时报错。你可以把这行删除试试看。
另外,Mocha内置对Promise的支持,允许直接返回Promise,等到它的状态改变,再执行断言,而不用显式调用done
方法。请看promise.test.js
。
详细请参考:http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html