在上一篇,簡單的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
這個博主還出了本書,我也買了一本在學習,實際上跟上面博客上寫的內容差不太多,看看上面的也就夠入門的了。