1. 程式人生 > >基於XML和Python實現白盒測試程式與測試用例分離

基於XML和Python實現白盒測試程式與測試用例分離

【摘要】進行白盒測試時,或者將測試用例和測試程式混在一起難以閱讀;或者花很大精力構思用例的格式,然後編寫較複雜的程式進行用例的提取;本文提出一種XML用例編寫規範和解析思路,它基於pythonXML解析器minidom,可以快速完成測試用例與測試程式分離。

   鑑於XML在資料傳輸上的優越性,無論基於何種語言而開發的專案,採用基於XML進行用例編寫,都將在通用性、相容性和程式易編性上收穫頗豐。

【關鍵詞】盒測試;XMLPython

Python XML解析器

終端UI採用了跨平臺語言Python進行開發,保證了一套UI可以不用修改即可在眾多主流作業系統上使用;採用python的解析器

parseXML進行解析的程式同樣可以在這些作業系統上執行,這樣我們的測試用例也是一套跨平臺的用例,這種通用性極大的提高了效率。minidomdom資料夾下,具體結構如下所示:

Python25/ Python2.5 安裝根目錄 (可執行檔案的所在地)

|

       +--lib/ 庫目錄 (標準庫模組的所在地)

|

+-- xml/ xml (實際上目錄中還有其它東西)

|

+--sax/ xml.sax (也只是一個目錄)

|

+--dom/ xml.dom (包含 minidom.py)

|

+--parsers/ xml.parsers (內部使用)

Python

解析一個XML包只需要兩句話:

from xml.dom import minidom

xmldoc = minidom.parse('pbkTestCase.xml')

第一句話匯入我們的minidom模組,第二句話將指定的XML檔案使用parse方法解析之,這是將整個XML文件一起讀取解析的。 minidom.parse 返回的物件是一個 Document 物件,它是 Node 類的一個子物件。這個Document 物件是連鎖的 Python 物件的一個複雜樹狀結構的根層次,這些 Python 物件完整表示了傳給 minidom.parse XML 文件。每個 Node 都有一個 childNodes

屬性,它是一個 Node 物件的列表,我們正是通過這種樹型結構,逐層的找到所需要的資料。

XML測試用例格式約定

XML測試用例格式有如下三條約定:

(1) <function></function>作為一個測試函式的起始和結束標誌;

(2) <ref></ref>作為一個測試用例的起始和結束標誌;

(3) <p></p>作為一個測試用例的引數的起始和結束標誌;

每個測試文字包含眾多的 ”function” ;每個 ”function” 包含眾多的 ”ref” ;每個 ”ref”包含眾多的”p”。這樣的XML文字便包含了眾多的節點和子節點,採用上節提到的childNodes屬性可以很容易的找到各個節點3層結構使整個用例看起來比較明晰,而且每層使用統一的識別符號,簡化了解析程式的編寫。一個完整的例子如下:

<?xml version="1.0"?>

<!DOCTYPE phonebook>

<phonebook>

<function id="test_CreatCategories">

<ref id="1">

<p> Mn*$</p>

<p>AppGlobals.TpvSimPbPC</p>

</ref>

<ref id="2">

<p>#12Ab&%</p>

<p>AppGlobals.TpvSimPbSIM</p>

</ref>

</function>

</phonebook>

上面是一個名片夾建立群組的兩個用例,一個在PC側建立名稱為”Mn*$”的群組,另外一個是在SIM卡上建立名為”#12Ab&%”的群組。每個函式都有唯一的ID,便於解析程式提取此函式,ID的值不侷限於數字,我們是將ID賦成每個測試函式的名字,這樣解析程式將其作為字典的鍵,可以很明顯的與測試函式對應,便於維護用例和程式。

測試用例的解

上述測試用例的編寫規則給解析用例帶來了很大的便利。由於每個函式、每條用例及引數的標誌固定,根據不同的ID即可將所需要的資料提取出來。解析過程如下:

(1) 通過getElementsByTagName屬性找到每個測試函式;

(2) 使用attributes[u"id"].value,通過不同的ID,得到測試函式名,作為儲存測試用例的字典的

(3) 通過getElementsByTagName屬性找到測試用例和用例引數,將其存入列表後,作為測試函式對應的存入字典;

(4) 新增一定的判斷邏輯,給編寫測試用例提供一些方便,比如測試用例的引數過長時,進行換行等。

下面是解析過程的python程式描述:

def importFile(path):

funcTC = {} #定義一個字典,用來儲存測試用例的鍵-值

xmldoc = minidom.parse(path) #解析path路徑下的某XML檔案

funcList = xmldoc.getElementsByTagName_r(u'function')

for i in range(len(funcList)):

#根據不同的ID,得到每個測試函式的函式名

          funcName = funcList[i].attributes[u"id"].value

          #根據不同的refp,得到每個測試函式對應的測試用例其用例引數

     refList = funcList[i].getElementsByTagName_r(u'ref')

refTC = [] # 測試用例儲存到列表中

for j in range(len(refList)):

pList = refList[j].getElementsByTagName_r(u'p')

pTC = []# 測試用例的引數也儲存到列表中

for k in range(len(pList)):

# 對用例引數的換行輸入進行識別

temp1 = pList[k].firstChild.data.split(u'/n')

for w in range(len(temp1)):

# 對用例引數的空格和tab鍵進行識別

temp1[w]=temp1[w].strip(u'/t').strip()

temp2 = ''

for q in range(len(temp1)):

temp2 += temp1[q]

pTC.append(temp2)

refTC.append(pTC)

funcTC[funcName] = refTC # 測試用例存入字典中

      return funcTC #返回我們從XML中提取的有效的測試用例資料

以我們上述建立群組的用例說明,我們的解析程式返回的資料如下:

funcTC={u'test_CreatCategories':[[u'Mn*$',u'AppGlobals.TpvSimPbPC'],[u'#12Ab&%', u'AppGlobals.TpvSimPbSIM']]}

測試用例在測試程式中的使用

由於有效的測試用例已經在字典中儲存,測試程式可以非常方便的使用字典的鍵-值來獲取需要的資料。測試程式只需要進行以下幾步即可獲取需要的資料:

from allTestCaseXml import importFile

    pbkTestCase=importFile("./pbkTestCase.xml")

for i in range(len(pbkTestCase['test_CreatCategories'])):

[groupName,Flag]=pbkTestCase['test_CreatCategories'][i]

首先,匯入importFile函式,獲取儲存有效用例的字典,最終從其中獲取到需要的兩個變數群組名groupName和儲存位置Flag,測試程式即可使用這兩個變數。

效果評價

本文提出的用例的分離思想簡單易行,由於採用了XML編寫用例,通用性很強,這樣的一套用例不僅能夠跨平臺使用,也可以使用各種開發語言對其進行解析,適用於各種語言開發的終端軟體。

測試用例與測試程式的分離使得用例編寫和程式編寫可以獨立進行,程式設計人員可以把精力投入到測試程式的編寫中,測試用例由其他人員編寫和修改,既保證了用例的覆蓋率,又提升了測試程式的開發效率。

參考資料

Dive in Python