前段時間充忙的學習RF,系統學習完之后就開始動手做各種接口的測試,雖然各類的接口測試基本能跑通了,但是重復造車的問題存在太明顯。RF本身內置庫就已經比較豐富,比如不需要import直接就加載到內存的BuiltIn庫,還有需要import的常用模塊String,Collections,XML庫。在前面的接口測試中,使用最多的就是這幾個內置庫,接口返回的數據基本都是xml格式的居多,然后自己也重復造車了,為此特地花了幾天時間去學習了下內置庫,主要還是學了下XML庫,以下的分享都是基於XML庫。
學習XML內置庫,我認為需要掌握以下幾個知識點:
第一:內置庫的概念?有哪些內置庫,大概都有什么關鍵字?有區分版本嗎?跟RF版本有關么?為什么內置庫有些需要import,有些不需要import?
第二:XML內置庫使用的是python的哪個標准庫?對這個標准庫需要有哪些基本的了解?
第三:內置庫是怎么構建起來的?基本關鍵字是否能靈活的使用?
第四:有時候可能需要稍微修改下內置庫,比如增加一些關鍵字等,該怎么修改?
從網上和官網(http://robotframework.org)上搜到一些資料,整理如下:
第一:內置庫的基本概念?
內置庫實際在官網稱為standard library,就是標准庫。常見的其他庫比如Request,SeleniumLibrary庫,官網稱之為external library,就是外部庫,也稱第三方庫。標准庫和外部庫首先要正確的進行區分,對於標准庫,這些庫是直接綁定在RF內的,在
不同版本的RF,支持不同的內置庫而且相同的內置庫里的關鍵字可能也是不一樣的,以RF3.0(使用命令robot --version查看RF版本)為例,3.0是目前最新的RF的版本,支持很多的內置庫,查看D:\Python27\Lib\site-packages\robot下的py文件,可以看到:
基本官網寫的10個標准庫都能在這里面找到相應的py文件。BuiltIn,Collections,DateTime,Dialogs,Process,OperatingSystem,Remote(沒有關鍵字,暫時不算在內),Screenshot,String,Telnet,XML.這11個庫,有些是在RF2.0的時候就已經有了的,最晚的DateTime,Process,XML是在RF2.8之后才內置的,也就是說如果當前使用的是RF2.8之前的版本,內置庫是無法直接import XML就是使用的,需要下載安裝才能使用,這點需要注意下,不同的RF版本,相同的標准庫之間也是會細微的區別,這需要仔細的去查看保准庫內每個版本的使用文檔。
10個標准庫,又都是做什么用的呢,這還真需要了解,而且還需要多花時間去了解每個標准庫里面的關鍵字,這10個標准庫,介紹如下:
這個表的來源是來自官網的,官網的用戶手冊文檔已經描述的非常詳細了。學習的時候可以詳細的查看官網的相關文檔。
第二:XML內置庫的學習。
從內置庫的XML的源碼可以看出,RF使用的是ETree來對xml進行解析的,部分源碼如下:
import copy import re import os try: from lxml import etree as lxml_etree except ImportError: lxml_etree = None from robot.api import logger from robot.libraries.BuiltIn import BuiltIn from robot.utils import (asserts, ET, ETSource, is_string, is_truthy, plural_or_not as s) from robot.version import get_version should_be_equal = asserts.assert_equal should_match = BuiltIn().should_match class XML(object): ROBOT_LIBRARY_SCOPE = 'GLOBAL' ROBOT_LIBRARY_VERSION = get_version() _xml_declaration = re.compile('^<\?xml .*\?>')
use_lxml = is_truthy(use_lxml)
if use_lxml and lxml_etree:
self.etree = lxml_etree
self.modern_etree = True
self.lxml_etree = True
else:
self.etree = ET
self.modern_etree = ET.VERSION >= '1.3'
self.lxml_etree = False
if use_lxml and not lxml_etree:
logger.warn('XML library reverted to use standard ElementTree '
'because lxml module is not installed.')
def parse_xml(self, source, keep_clark_notation=False):
with ETSource(source) as source:
tree = self.etree.parse(source)
if self.lxml_etree:
strip = (lxml_etree.Comment, lxml_etree.ProcessingInstruction)
lxml_etree.strip_elements(tree, *strip, **dict(with_tail=False))
root = tree.getroot()
if not is_truthy(keep_clark_notation):
NameSpaceStripper().strip(root)
return root
python提供了幾個標准庫都可以對xml進行解析,之前我使用的是DOM,基於RF使用的是ETree,便開始學習了下ETree的開發文檔。學習對XML文件的操作,那肯定也得對XML本身有最基本的了解,比如XML的用途,樹結構,節點類型(DOM),帶命名空間的xml。下面是部分的知識點的總結:
xml是一種可擴展的標記語言。要求標記需要成對的出現(有時候會進行簡寫<b/>)。一個典型的xml文檔如下所示:
<example> <first id="1">text</first> <second id="2"> <child/> </second> <third> <child>more text</child> <second id="child"/> <child><grandchild/></child> </third> </example>
A. 整個xml文檔是一個文檔節點,屬於根節點,比如上述文檔的<example>節點就是一個根節點,一個xml文件只能有一個根節點,否則解析的時候胡報錯的
B.每個 XML 標簽是一個元素節點,比如<first> 和<second>, <third>都屬於元素節點,卻屬於<example>的子節點。
C.attribute值:表示節點元素的屬性值,比如first 有一個屬性id,屬性值為1;second也有id屬性,屬性值為2,而third沒有屬性。
D.Text值:表示元素中的文本內容。比如:first 的text值就為1;second沒有,third也沒有;
一個xml還包含其他的內容:比如處理指令和一些注釋;在python的etree標准庫解析的過程中,是直接把這二個給剔除掉了。有興趣的可以根據官網給出的開發文檔,把常用的一些方法都敲一遍,主要的還是使用2個類 Element Objects和ElementTree Objects。
第三:RF中XML庫的學習。
在使用sudslibrary做soap協議的測試時,返回的xml是帶命名空間的,之前一直不理解,對XML庫進行整體的學習之后就有了很大的理解。
XML庫主要有以下幾個作用(翻譯於原文手冊):
A. 解析一個XML文件,或一個包含XML的字符串,在一個XML元素結構中,並從中尋找某些元素,用於進一步分析 (e.g. Parse XML and Get Element keywords).
B. 獲取元素的文本或屬性(e.g. Get Element Text and Get Element Attribute).
C. 直接驗證文本、屬性或全部元素 (e.g Element Text Should Be and Elements Should Be Equal).
D. 修改和保存它(e.g. Set Element Text, Add Element and Save XML).
下面按照關鍵字的類型大致做了以下的學習:解析的xml都是前面的xml例子
A.最常用關鍵字的學習:
B. 通過xpath來搜素子節點。
C. 簡單的帶命名空間的xml的解析
D. 復雜的命名空間的xml解析(之前soap協議返回的xml的解析部分補充)