655
技術社區[雲棲]
構建理想的模塊自測結構
構建理想的模塊自測結構
溫輝敏(wenhm@sina.com)
軟件測試的工作量很大(業界統計達到40% 到60%的總開發時間),而又有很大部分適於自動化,因此,測試的改進會對整個開發工作的質量、成本和周期帶來非常顯著的效果。
極限編程(XP)中推薦的自動化單元測試,是指在編寫代碼之前先寫好測試代碼,代碼編到一定階段就用寫好的測試代碼進行測試。自動化單元測試可以帶來如下好處:
l 由於測試代碼(測試用例)的不斷增加,這些測試總讓我們寫出的代碼往正確的方向靠攏,使我們不至於重犯以前的錯誤。
l 由於可以實現自動測試,所以可以很好的解決人工很難進行的回歸測試問題。
我們沿著“建立測試=>令測試通過=>再建立測試=>再令測試通過”的模式,一步一步地把整個程序正確地開發出來。
1.測試代碼的幾個關鍵環節
1)將測試數據和測試結果從測試代碼中分離出來
在采用CXXUNIT係列測試工具開發測試代碼時,發現一般編程人員都是測試用例和測試代碼混雜在一起,同樣測試結果也是和測試代碼混雜在一起,這樣就導致測試用例和測試結果的管理非常困難,因為要管理每個用例的數據和結果實際上就是去管理這些代碼。而且對於一個函數(或功能) 每增加新測試用例,就要多出一份類似的代碼,代碼的邏輯實際上都是一致的,和以前測試代碼的不同點就是在初始化數據、測試結果的不同,這實際上也導致了代碼的重複。
我們可以將測試數據和測試結果從測試代碼中分離出來,使得某一個函數(或功能)的測試代碼就一份,這一份測試代碼應可以進行多組測試數據的測試,可以進行多組測試結果的驗證。
2)將測試數據和測試結果放入文件中,並按目錄存放
將測試數據和測試結果從測試代碼中分離出來是為了更好的管理代碼和測試數據,將每個測試用例的數據和結果都放入到一個文件中,文件名字或文件所在目錄起上能表明測試用例含義的名字,這樣管理起來就方便多了,見圖1-2。
圖1-2
由圖1-2中可以看出此時測試用例非常直觀,從目錄名就可以知道該目錄下的為那個功能的測試用例,從測試用例文件名就可以知道這個測試用例測的哪一個方麵。當一個功能的測試用例非常多可以分成許多類別時我們還可以在下麵再創建測試用例分類子目錄,使得不同類型的測試用例能分隔開方便管理(詳見圖2-1)。
3)將測試數據和測試結果綁定在一起
當每個測試用例對應的測試結果都一樣時可以將測試結果嵌入到測試代碼中,當不同的測試用例要對應不同的測試結果時,根據1)中論述應該將測試結果也從測試代碼中分離出來。為了不混淆測試數據和測試結果之間的關係,將它們放在同一個文件中。這裏舉個例子,圖1-2中的“閏年2月份的測試用例.ini”文件中內容如圖1-3:
1-3
由圖1-3可以看到,測試數據和測試結果放在一起,增加了可讀性和維護性。
4) 一份測試代碼來運行多份測試用例
怎樣讓一份測試程序可以進行多組數據的測試和結果的比較呢?3)中已經將測試用例分門別類,並由相應的目錄結構組織起來。此時測試程序隻需每次從測試目錄中取出一個測試用例文件,進行初始化,然後執行測試,最後比較測試結果;測試完一個用例文件,再取下一個文件進行測試,如此循環直到所有的用例文件都測了一遍,詳見圖1-4。
1-4
2.測試用例管理方案設計
若再加上邊界數據要測試的數據組數就更多了,一般CXXUNIT係列編寫的測試代碼是每組測試數據(其實一組數據就對應一個測試用例)都要編寫初始化代碼,然後調用相應功能函數測試。這樣導致:
在自動測試的整個過程中,測試用例的可維護性會影響到將來測試用例增加的難易度,良好的自測程序應能很方便的擴充測試用例。
在采用係列測試工具開發測試代碼時,對於一些簡單的測試可以測試用例就嵌在測試代碼中。但當某一個功能或函數要進行很多組數據如邊界數據的測試時使用這種方法就得重複編寫測試代碼,可能每增加一個測試用例就要編寫大量的重複測試代碼。
舉例:要測試周期會議預約功能的代碼,要測試以下幾組數據:
每日召開的周期會議
按召開次數預約的周期會議
按開始時間、終止時間預約的周期會議
每周召開的周期會議
……內容和、一致
每月召開的周期會議
……內容和、一致
每年召開的周期會議
……內容和、一致)
l 隨著測試數據組數的增加,將出現大量做重複動作的測試代碼,這些測試代碼之間唯一的不同是由於初始化的數據不一樣而已。
l 當一個功能隻需一兩個測試用例時,測試用例嵌入在測試代碼中可以進行控製和管理,當一個功能測試時需要大量的測試用例時(見舉例),大量的測試用例嵌在代碼中將很難管理,你要知道某個用例是否已經有了還得去遍曆測試代碼比較麻煩。
測試用例目錄結構
為此很有必要設計一套能良好管理和添加測試用例的體係結構。
當一個功能有很多組測試數據時,我們可以將測試用例數據全部存放在文件中,使測試用例和測試代碼分離開。由於測試用例脫離測試代碼而存在,可以很方便的進行管理和維護。我們可以為每個要測試的函數(或功能)建個目錄,每個測試用例放在一個單獨的文本文件中,將所有對應於該函數的測試數據文件全部放入該目錄下,當測試數據量很大時還可以在目錄下再創建相應的子目錄,分類進行管理。這樣可以方便測試用例的管理,而測試程序也隻用專注於測試邏輯。還以測試周期會議預約功能的例子為基礎進行討論。
由圖2-1上可以看到,當某個函數(或功能)的測試用例很多時,還可以在“某功能測試用例總目錄”下再使用子目錄來劃分,若覺得劃分不夠細還可以繼續加深目錄層次,直到分類比較清晰為止。
由於測試用例數據和測試代碼進行了分離,以後對於某個函數(或功能)有了新的測試用例時不用再去修改測試代碼,隻需在該功能的測試數據目錄下添加新的測試用例文件即可。該功能的測試程序每次運行時對於相應測試數據目錄下的每個測試用例文件(包括各級子目錄下的用例文件)都要執行一遍。
使用了目錄結構對它們進行了分門別類方便了以後的管理,正如良好的程序應具有好的可讀性和維護性一樣,良好的測試數據也應具有好的可讀性和維護性。
測試用例文件結構
測試用例文件中存放測試用例初始化數據和測試完畢後的驗證數據。數據的結構采用一般配置文件的格式,詳見圖2-2。
1)段名
配置文件中使用了段的概念,段相當於C++中的NameSpace,每個段內的關鍵字(Key)與其它段內的關鍵字互不影響,Section即為段名。
2)關鍵字
關鍵字用來標誌不同元素的值,Key即為關鍵字的名字,關鍵字的名字不區分大小。
3)值
每個關鍵字都對應一個值,Value 即為值,值要區分大小。
4)注釋
支持單行注釋,字符“#”後麵的內容為注釋。
5)行結構
一行的結構隻能是以下幾種:
l [Section]
l Key=Value
l 空行
l 以上三中情況之一加上注釋
測試程序通用庫
測試數據從測試代碼中分離出來後,增加了管理測試數據文件和解析測試數據文件的代碼,這部分代碼是通用的,可以將它們組織成庫供開發測試程序時使用。

2.3.1管理測試數據文件的庫
管理測試數據文件的庫的功能如下:
1)獲取目錄下所有測試文件路徑的接口
能找出某個目錄下 (包括該目錄下所有子目錄)所有的測試文件(如“*.ini”文件)的路徑並存起來。
2)獲取下一個測試文件的接口
向用戶提供下一個測試文件的路徑,若已沒有下一測試文件則返回空。
2.3.2解析測試文件的庫
解析測試文件的庫的功能如下:
1)文件解析接口
按照 2.2測試用例文件結構 中的文件結構解析出一個測試文件。
2)獲取值的接口
向用戶提供測試文件中某個段內某個關鍵字對應的值。
由於測試文件的結構和一般配置文件結構一致,可以使用已有的庫來實現(如PWLIB中配置文件解析類)。
3.總結
一個完整的測試用例包含測試數據和測試代碼,當測試數據和代碼混在一起時給測試用例的維護帶來了很大困難,而且給測試代碼帶來許多冗餘。本文提出了將測試數據和測試代碼分離的想法,並對怎樣進行分離進行了闡述。測試數據從測試代碼中分離出來後,使得測試數據維護簡單、方便。
最後更新:2017-10-26 14:04:07