nightmare自动化实践
01 Apr 2017
以前偶尔听到自动化测试
这个概念,但一直对其一头雾水,前端界面主要也就是UI
,怎么才能做到自动化呢?还是在跟前同事交流过程中,他提到了nightmare
工具。于是就去看了一下,感觉是一款神器,其主要通过编写脚本,运行node来模拟浏览器访问和交互,底层基于electron
。可以做到同时打开electron
窗口,方便调试跟踪,其api用法比phantomjs
更为简单好用!
安装注意
npm install nightmare
nightmare
依赖electron
,貌似需要用到python
,比如window系统可能没装python的话,在安装nightmare
时会报错说找不到python
的环境变量,建议装个python2.7
先。
基本用法
如下代码:
还有一些常用的api
,如type
输入操作,click
点击操作等等。具体可以参考»
要注意的地方
evaluate
方法,方法的参数函数的执行环境是浏览器环境,而不是脚本的运行环境,因此,其内部无法访问到脚本内定义的全局变量,但是可以通过evaluate
的后续参数,来作为第一参数函数的参数传入。
比如
虽说如此,但是!!!这种方法不能传一些特殊对象,比如原型链上的内容,是不会带上的,而且即使说node环境有Date对象,浏览器也有Date对象,也不能直接传入一个Date的实例,传入之后,也用不了Date的内置方法。
then
的重要性:最上面的示例代码里注释也有提到,需要加入then才能保证队列的执行.
引用这里的一句话
这是因为每一个 nightmare 实例都有一个操作队列,而这个操作队列保存着 nightmare 的一系列操作。而 nightmare 的每一个链式调用只是将操作保存到队列里面,并没有立刻执行操作。
关于这个队列操作,可以读一下nightmare源码,nightmare的实例对象中都有一个_queue
的数组,用来保存每一个基本api动作,等到调用then
时,才去触发run
函数,从而去处理_queue
里的一个个动作。
实践例子
我在sf里,时不时就去审核中心处,做一下一些挖坟问题审核,时间久了,各种挖坟回答就多起来了, 作为强迫症的我,发现点来点去都是些重复操作,大部分可以拒绝通过的回答,无非就是问解决了没有、顶等等无意义的回答。(这种跟帖式的回答真是令人反感,一个好端端的问答模式,你偏偏当做论坛来用。)
于是我考虑,写个脚本来自动化审核,过滤掉这些跟帖式回答处理(直接拒绝通过,需要投三票才真正拒绝,所以也不是说我说拒绝就一定拒绝。)
nightmare提供了一个良好的使用环境,可以模拟人为操作,很是方便,不用像写爬虫那样去模拟登录,而是写代码来替代那些人为操作,由于这种需要使用nightmare做一些循环跳转,于是我便定下了一个逻辑代码基本套路,如下
就顺着这个基本套路,也就差不多能做点东西了,再通过事先分析页面,主要操作是在evaluate内做判断和数据处理,通过then收集数据,并在end最后做日志记录。
我的审核脚本大致是这样的:
一下子,需要审核两百条挖坟信息,脚本就帮我做了,省下时间去干别的事儿了。
期间,要留意的问题是分析页面dom要到位,确保wait选择器的时候,这选择器是必然存在的,不然,结局就会是脚本一直在等待,直到最后跳出,中断了后续运行。
综上,上述只适用于简单用户名和密码登录的网站,如果是需要验证码的那种,可能就没那么好做了,但可以考虑打开electron
窗口,做半自动化模式。可以参考这里
–update:
最近简要的翻了一下nightmare的源码跟api文档,发现evaluate
还有另外一种用法:
前面提到的evaluate
,这里then里的function获取到的data,其实就是fn的返回内容。但如果fn的参数设定大于arg(即evaluate总参数个数-1)时,fn的最后一个多余的参数为done,其实是nightmare给添加进去的,这个时候evalute
的结束返回机制就变了,此时直接return
不会执行后续的end()
来关闭窗口,而是一直等待evaluate的timeout,归根于此时的fn内部需要显示调用done(err,data)
来结束evaluate
.
举了简单代码例子:
这里then的function最终获取到的是hello
, 这种写法可用于在浏览器端做异步调用结束运行。
参考
使用 nightmare 进行页面测试介绍
nightmare官网
http://gewenmao.github.io/2016/web/nightmare-with-command-line-prompt