在上一篇,简单的demo实现了讲xml的数据发送服务器端并取得recvi_buf,然后进行了简单的解析的操作。现在就要解决之前提过的2个问题:
1. 步骤这么多,难道每写一个脚本都要重复一次么?
2. 每个接口的sendbuf的xml的格式是不一样的,id不一样,里面的tag的nodename也是不一样的,这要怎么办?难道每个接口都给写一个createSendBuf么,肯定不是这样的,那要怎样去做?
针对第一个问题的解决,可以使用在RF内定义自己的Resource,然后写直接调用资源内定义的关键字,一行就是一条测试用例,这个问题解决很简单。针对第二个问题,应该用一个xml文件保存每个接口的格式,定义个一个关键字,输入接口的id,就能从xml中得到相应接口的格式,再从RF内接受接口里每个字段的取值,一起组合成send_buf,交给底层py调用含有网络通讯层的dll即可。
从xml根据id得到相应接口的报文格式的实现如下:
def findNodeByIdAttr(self,idAttr): root = xml.dom.minidom.parse("D:/test2.xml").documentElement node = root.getElementsByTagName('cmd') for k in node: if(k.getAttribute('id')==idAttr): str1= (k.toxml()).encode('utf-8') return str1
这样就能更容易的管理报文了,如果增加了一个接口,直接在xml内进行格式定义即可。代码内部是没有涉及到具体报文里的具体字段,便于维护。接下来就是把从RF里得到的报文字段的取值(定义在list内),把具体值和对应的xml组合起来。toxml()方法返回的数据的type不再是一个instance,而是str(egg:<cmd id="30000"><UserName var="name"/><LoginServerAddr var="www.abc.com:1089"/><UserPassword var="000000"/></cmd>),list的值为['loleina','192.165.5.144:1089','000000']现在就需要把这三个指分别赋值给UserName ,LoginServerAddr ,UserPassword 。得先将str转换成xml,再得到xml的tag的name,设置每个tag的attribute的值是list[i].代码实现如下:
def packageToXml(self,strNode,listArray): tagNameList=[]
length=len(listArray) str1='<?xml version="1.0"?><root>' str2='</root>' strNode+=str2
strNode=str1+strNode
root = xml.dom.minidom.parseString(strNode).documentElement node = root.getElementsByTagName('cmd')
for child in node[0].childNodes:
if((child.nodeName.startswith('#'))==False):
tagNameList.append(child.nodeName) for i in range(0,length):
tagNode = root.getElementsByTagName(tagNameList[i])
tagNode[0].setAttribute('val',listArray[i]) return node[0].toxml(encoding="utf-8")
最后看下,RF的测试用例的设计:
就这样完成了demo,在最开始的时候遇到了好几个问题:
1. 项目的接口有多个xml,需要合并成一个xml提供给RF使用,每个xml的格式不一样,编码格式也不一样,而且xml里针对每个字段有注释,commentnode存在,得把注释去掉。(后面发现不去掉注释的xml,不去掉空格,空行的xml,交给底层的dll后,dll会进行预处理,整理好后再发给服务器)
2. 在xml内取tag的name的时,如果tagnode有childnode,按照上面的代码段是没有取出来的,这个后面得修改。
3. 从服务器返回的数据,根据接口类型的不同,增加类,删除类的接口或者只返回一个result字段的结果,查询,修改这类接口会返回很多的数据,数据还是从数据库查到的,这样结果这样简单的
处理肯定是不行了。得从数据库中查询,再按照一定的格式组装成xml,在把预期的结果xml和实际返回的xml做对比。
4. 去tagnode的name的时候,得判断下,因为xml内存在注释,注释也是一种node,称为commentnode。
5. 基于winsocket的接口测试跟基于http接口测试还是有很大区别的,http是无状态的协调,tcp本身就是有状态的协议。这注定前置的业务肯定比后者复杂很多,基于winsocket的接口,接口和接口之间的联系,存在一些运行时的临时变量,也就是说B接口的报文组成,来自于A接口报文的某些输出,该部分输出作为程序运行的临时变量,保存在程序内存中,而非数据库中,当B接口使用,就去拿就可以了。这时,做B接口势必需要拿到A的结果里的临时变量,这个随着后面业务的深入了解,应该会越来越明朗每个接口之间的关系。
这些问题在再深入点了解RF和Python,做demo的时候,就开始不断的思考了。在这推荐一个还不错的RF的学习网址:
http://blog.csdn.net/tulituqi/article/category/897484/2
这个博主还出了本书,我也买了一本在学习,实际上跟上面博客上写的内容差不太多,看看上面的也就够入门的了。