对比上面的第一个脚本,可以看出关键字驱动进一步屏蔽了底层的实现细节,例如,你只需要clickAndWait那个btnG,而不需要知道btnG到底是个啥,以及它在哪里,你只需要填写表格。等你把一个个 test case 变成了一个个表格,把一个个step变成了一行行表格中的内容,基本上你的自动化测试就搞完了。——真的是这样吗?
现在回想一下,关键字驱动之所以会出现,可能初衷还是为了降低自动化实施的门槛——因为tester都不太懂开发嘛,所以开发能力强的人把框架实现出来,原来那些只会写excel的 system tester填写表格就可以了。也许现在还有很多公司会倾向于这个方案,美其名曰“分工协作,人尽其能”。不过关于这个问题,暂时先不展开讨论,先看看这种传统的关键字驱动模式会遇到什么问题。
首先,页面对象的识别问题。这是任何一种基于UI实现回归测试自动化的框架都会遇到的问题。在C/S时代,就已经出现了很多定制化UI组件难以被工具识别的问题,可好歹总逃不出windows的手心。到了web时代,前端实现技术百花齐放,而前端代码的编写也更是一个开发人员一个习惯,如果缺少统一的编码规范,对于那些没有使用id或者name之类属性的页面对象,传统的关键字驱动框架就没有例子中看起来那么美好了。当然,有人说xpath可以解决一切问题。嗯,xpath是很强,但是一个没有开发经验的tester 想掌握它其实也不会比学会一点基本的编码技术容易多少;另外,xpath并不是万能的,在实际中还是有些它处理不了的情况。下面再给个例子(如果 tester看不懂这个例子,估计学会xpath也有点困难):
上面这个图中是一个表格,id列(第一列)和需求名称列(第二列)下显示的内容,都是可以点击的超链接,最后的“操作”一列中的一个个小图标也各自指向一个链接(分别是“变更”、“评审”、“编辑”、“建用例”),通过查看第一行记录的html代码,我们发现:
1.假如想要编辑一条记录,没有可利用的id或name属性,唯一可用的是link;
2.link指向的url中包含了这条记录的ID信息,因为这里是第一行记录的代码,所以都是341,而后面的每一行记录的代码都是各自的ID。
上面这个例子是企业应用中常见的场景,关键问题在于数据记录ID 是一个不可控因素,而数据记录的title/name之类的是可控的,为了提高test case的可维护性和相互独立,我们肯定不会依赖ID去模拟页面操作,而是根据title/name之类取回ID信息,再拼装回所需要操作的链接。这种情况下,xpath恐怕也搞不定了。(如果这里再涉及到要在几个iframe之间跳来跳去,恐怕写脚本的人就要崩溃了。)
当然,有人会说关键字驱动框架一般也可以定义function来实现类似的操作啊。唉,都到了编写自定义function的地步了,干嘛还非要纠缠在关键字驱动上啊。
第二,脚本的可维护性问题。如一开始的例子,传统的关键字驱动是一种纯“面向过程”的脚本组织方式(就像C/pascal),表格中填写的是一个操作序列。如果多个test case 都涉及到某个页面,基本上就会在多个case中都看到类似 clickAndWait btnG这样的内容,而一旦页面中btnG改名叫buttonG了,或者 clickAndWait btnG与verifyTextPresent 之间增加了一个 clickAndWait XXX的step,那基本上每个case都需要修改。
嗯,问题来了,当你的脚本数量从1增长到100、1000的时候,当UI的变动无法避免的时候,当你发现100个case回归执行只有90个通过,执行失败的10个需要逐个检查错误日志和查看截图,再挨个修改的时候,当下次回归测试又发生这种问题的时候——基本上这就是一个死循环了。如果解决不了根本问题,前期投资可以舍弃了,别纠结了。
当然,有人说关键字驱动已经进化了,可以跟最新的webdriver结合起来,提升关键字的封装层次,解决这个可维护性的问题。好吧,这个问题等下再详细说。
第三,脚本的可扩展性问题。在大规模实施自动化的过程中,脚本一般都会简单的是一行行的browser.find_elmenet_by_id(xxxx).click() 这样的模式,根据各种条件来判断执行的分支,进行各种异常处理,第三方类库/包的调用,主机环境的访问,诸如此类,这些对于所有的3GL/4GL来说其实都很容易实现,但对于传统的关键字驱动来说,嗯,也可以实现,大概是下面这个样子【摘自robot framework(此robot非rational robot)】:
原文转自:http://www.uml.org.cn/Test/201501065.asp