测试方法+工具

天气小雨,不宜出门。只好在家好好修炼,正好准备总结一下测试相关的知识。主要总结以下项目中用到的前端测试工具:

  1. mocha-phantomjs+chai来实现自动化单元测试
  2. nightWatch 实现端到端的集成测试

<a href="https://www.a2doc.com" target="_blank" rel="noopener noreferrer">前端</a>测试方法+工具

mocha+chai

Mocha(发音”摩卡”)诞生于2011年,是现在最流行的JavaScript测试框架之一,在浏览器和Node环境都可以使用。Mocha的作用是运行测试脚本,通常,测试脚本与所要测试的源码脚本同名,但是后缀名为.test.js(表示测试)或者.spec.js(表示规格)。比如,add.js的测试脚本名字就是add.test.js。

上面这段代码,就是测试脚本,它可以独立执行。测试脚本里面应该包括一个或多个describe块,每个describe块应该包括一个或多个it块。
describe块称为”测试套件”(test suite),表示一组相关的测试。它是一个函数,第一个参数是测试套件的名称(”加法函数的测试”),第二个参数是一个实际执行的函数。
it块称为”测试用例”(test case),表示一个单独的测试,是测试的最小单位。它也是一个函数,第一个参数是测试用例的名称(”1 加 1 应该等于 2”),第二个参数是一个实际执行的函数。

chai是一个断言库,断言的意思类似于语言,就是1+1应该等于2,描述类似的这样的预言,断言和预言的区别在于断言的结果是必定发生的,断言的结果是准确的,如果发生错误只可能是执行断言的函数发生了错误,所以就可以定位是测试的函数有bug。所有的测试用例(it块)都应该含有一句或多句的断言。它是编写测试用例的关键。断言功能由断言库来实现,Mocha本身不带断言库,所以必须先引入断言库。

断言库有很多种,Mocha并不限制使用哪一种。上面代码引入的断言库是chai,并且指定使用它的expect断言风格。
expect断言的优点是很接近自然语言,下面是一些例子。

基本上,expect断言的写法都是一样的。头部是expect方法,尾部是断言方法,比如equal、a/an、ok、match等。两者之间使用to或to.be连接。对于结果值的判断用to.be链接,而对于结果是函数的判断通过to链接。
有了测试脚本以后,就可以用Mocha运行它。

上面的运行结果表示,测试脚本通过了测试,一共只有1个测试用例,耗时是8毫秒。Mocha默认运行test第一层子目录里面的测试脚本。所以,一般都会把测试脚本放在test目录里面,然后执行mocha就不需要参数了。为了改变默认运行test第一层子目录这种行为,就必须加上–recursive参数,这时test子目录下面所有的测试用例,不管在哪一层都会执行。mocha目录同样支持通配符,如下:

关于mocha其他的参数,可以查看 mocha -h
详细参考阮老师文章: https://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html

es6编写测试脚本

测试用例可以采用es6来编写,如下:

执行测试用例之前需要采用babel转义es6,

然后,在项目目录下面,新建一个.babelrc配置文件。

最后,使用–compilers参数指定测试脚本的转码器。

上面代码中,–compilers参数后面紧跟一个用冒号分隔的字符串,冒号左边是文件的后缀名,右边是用来处理这一类文件的模块名。上面代码表示,运行测试之前,先用babel-core/register模块,处理一下.js文件。由于这里的转码器安装在项目内,所以要使用项目内安装的Mocha;如果转码器安装在全局,就可以使用全局的Mocha。
下面是另外一个例子,使用Mocha测试CoffeeScript脚本。测试之前,先将.coffee文件转成.js文件。

注意,Babel默认不会对Iterator、Generator、Promise、Map、Set等全局对象,以及一些全局对象的方法(比如Object.assign)转码。如果你想要对这些对象转码,就要安装babel-polyfill。

然后,在你的脚本头部加上一行。

关于异步测试用例

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

上面的测试用例,需要4000毫秒之后,才有运行结果。所以,需要用-t或–timeout参数,改变默认的超时设置。

上面命令将测试的超时时限指定为5000毫秒。另外,上面的测试用例里面,有一个done函数。it块执行的时候,传入一个done参数,当测试结束的时候,必须显式调用这个函数,告诉Mocha测试结束了。否则,Mocha就无法知道,测试是否结束,会一直等到超时报错。你可以把这行删除试试看。
详细参考阮老师文章: https://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html

测试用例的钩子

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

详细参考阮老师文章: https://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html
附上阮老师的案例:https://github.com/ruanyf/mocha-demos

mocha API:https://mochajs.org/#getting-started

mocha bugs

在使用mocha在浏览器测试中遇到过一些问题,有些很难解决,比如:

上面这个在写异步测试用例,调用done方法后会报错,不一定都会,我遇到的是会报错,排查了很久,发现的原因是我写的测试用例是基于自己定义的 define函数和require函数来写的,在执行异步操作的时候,调用done方法的时候这个测试用例已经执行过了,导致调用done的时候,对应test为null,可以在这里写个debugger看下:

很是奇怪,分析了半天没找到原因,想想可能是我用的define和require的问题,于是把测试用例去掉define定义,直接用es6模块来写,然后运行时正常的,

chai

上面提到过,chai主要是一个断言库,用来实现断言的。chai提供了expect和should两种BDD风格的断言函数。

expect和should是BDD风格的,二者使用相同的链式语言来组织断言,但不同在于他们初始化断言的方式:expect使用构造函数来创建断言对象实例,而should通过为Object.prototype新增方法来实现断言(所以should不支持IE);expect直接指向chai.expect,而should则是chai.should()。
个人比较建议使用expect,should不仅不兼容IE,在某些情况下还需要改变断言方式来填坑。

chai API: https://chaijs.com/api/bdd/#
中文chai API: https://www.jianshu.com/p/f200a75a15d2

nightWatch

想起了守护长城的守夜人。官网:https://nightwatchjs.org/
Nightwatch是一套新近问世的基于Node.js的验收测试框架,使用Selenium WebDriver API以将Web应用测试自动化。它提供了简单的语法,支持使用JavaScript和CSS选择器,来编写运行在Selenium服务器上的端到端测试。

不同于行为驱动测试(BDD)和单元测试独立运行并使用模拟/存根,端到端测试将试着尽可能从用户的视角,对真实系统的访问行为进行仿真。对Web应用来说,这意味着需要打开浏览器、加载页面、运行JavaScript,以及进行与DOM交互等操作。Nightwatch尝试着使用语法糖(syntax sugar)来实现这一目标:

目前,Selenium是JavaScript的世界里验收测试方面最流行的工具之一,类似的还有PhantomJS。二者都有其独到的方法:Selenium使用其WebDriver API,而PhantomJS使用无界面的WebKit浏览器。它们都是非常成熟的工具,都具有强大的社区支持。它们与Nightwatch之间最大的不同,主要是在于语法的简易度以及对持续集成的支持。与Nightwatch相比,Selenium和PhantomJS都拥有更加冗长的语法,这会让编码变得更庞大,而且不支持从命令行中进行开箱即用的持续集成(JUnit XML或其他标准输出)。

使用方法

安装:

配置:
默认读取当前目录下的nightwatch.json文件,内容如下:

nightmare

nightmare现在也很好用,nightmare官网: https://www.nightmarejs.org/
A high-level browser automation library,基于浏览器自动化测试的API, 与nightwatch不同的是,nightmare采用的是基于 electron 的 headless 浏览器,封装提供了许多牛逼的API,包括导入js和css代码。但是貌似导入JS代码只能限于无模块(无AMD/CMD/UMD)的普通JS代码,否则js会报错,报错后的内容统统失效。导入的JS代码如果有错误,后面的错误都会被屏蔽掉。所以采用的方法是通过JS来加载JS代码。

谢谢!

转载请注明出处://fed123.oss-ap-southeast-2.aliyuncs.com/2017/03/05/2017_doTest/
请扫描左侧二维码,关注读书学技术服务号!每周更新学习文章以及技术书籍推荐哦!
欢迎关注皓眸学问公众号(扫描左侧二维码),每天好文、新技术!任何学习疑问或者工作问题都可以给我留言、互动。T_T 皓眸大前端开发学习 T_T



请遵守《互联网环境法规》文明发言,欢迎讨论问题
扫码反馈

扫一扫,反馈当前页面

咨询反馈
扫码关注
返回顶部