摘要:存儲過程的測試是一項非常繁瑣的工作,一些數據庫產品雖然提供了一些工具能夠統計出存儲過程的執行時間、返回記錄數等信息,但是這些工具不能進行批量的重復的測試,而且測試結果的顯示也不直觀。針對這些問題,介紹了在 Junit 測試框架下實現存儲過程自動化測試的方法,利用JUnit的自動化和生成的測試代碼的復用,可實現存儲過程的回歸測試,利用XML技術存儲測試用例和測試結果,實現測試用例和測試代碼分離,提高了測試效率,為開發人員提供了直觀的測試結果。
關鍵詞:存儲過程;自動化測試;測試用例;Junit框架;XML
中圖分類號: TP311文獻標識碼:A文章編號:1009-3044(2009)36-10252-02
Research on Automated Testing of Stored Procedure
MA Zhu-gen
(Department of Computer Science and Technology, Huaihua University, Huaihua 418008, China)
Abstract: Stored procedure test is an extremely tedious work.Some database products provide some tools to be able to make the statistics of the execution time of a stored procedure, the number of records and other information, but these tools can not carry on batch and repeated testing. Moreover,the test result is not intuitive. This paper describes the implementation scheme of stored procedure automation test under the junit framework.The code-reuse technique based automatic testing framework of Junitrealizes the regression testing of procedure. The test cases are described and organized using XML to realize the separation between code and data in order to improve efficiency of test, and the test result using XML provides developers with an intuitive notation.
Key words:stored procedure; software automation testing; test case; junit framework; XML
軟件測試是保證軟件質量的重要手段,軟件測試在整個項目開發中所占的比重也越來越大。隨著軟件規模的擴大和軟件復雜性的提高,軟件測試技術不斷發展,自動化測試技術得到廣泛應用,并逐漸成為軟件測試發展的方向。單元測試是軟件開發過程中要進行的最基本的測試活動,是確保其他測試能夠順利進行的基礎。隨著增量開發模式和重構技術的發展,軟件自動化測試工具JUnit也隨之產生。目前Junit已經成為Java程序單元測試框架的標準,已有多種對其進行擴展的自動化測試工具[1]。
存儲過程被廣泛應用在各種與數據庫相關的應用系統中。在開發階段,對存儲過程進行測試是必不可少的工作。通常的測試過程是由測試人員通過命令窗口執行命令,再將命令窗口中的結果信息拷貝下來,保存到一個文件里,在以后再進行分析或者比較。測試工作也可以使用類似Rapid SQL等圖形化的工具來輔助做一些工作,但能完成的測試工作量較少。這種大部分依靠手工進行的存儲過程的單元測試存在很多缺點,如測試效率低,無法重用,無法進行自動化的回歸測試,沒有直觀的測試結果,需要程序員手工整理測試結果并生成測試報告。針對這些問題,本文在Eclipse中利用Junit測試框架來實現存儲過程測試的自動化。
1 Juit的框架結構
Junit是Erich Gamma和Kent Beck編寫的一個回歸測試框架,它是一個Java程序自動測試的框架[2],用在軟件測試的單元測試階段,即Java對象類的功能測試。JUnit共有七個包,核心的包就是junit.framework和junit.runner。Framework包中包含了Junit測試類所需的所有基類,它是整個Junit的基礎框架[3],負責整個測試對象的構架,Runner則負責測試驅動。JUnit框架中主要有以下幾個對象類[4-5]:
1) Assert類,它提供在編寫測試時要用到的所有assert方法。當條件成立時assert方法保持沉默,但若條件不成立就拋出異常。Assert類是TestCase的父類。
2) TestCase類
客戶測試類所要繼承的類,負責測試時對客戶類進行初始化,以及測試方法調用。類中的主要方法有:setUp()用于如變量賦值等測試的結果處理,tearDown()用于如文件關閉等測試的結束處理,run()測試實例的執行,并把測試結果放入測試結果對象TestResult中。
3) TestResult類
負責收集TestCase所執行的結果。一般來說,用戶不需要對TestResult進行操作,測試結果由系統提供的測試工具自動輸出。
4) TestSuite類
TestSuite對象是測試實例的集合,負責包裝和運行所有的TestCase。
2 存儲過程測試代碼的自動生成
Junit測試的實現流程就是繼承TestCase類,然后重載它的一些重要方法,如setUp()、tearDown(),最后將這些對象組裝到一個Testsuite對象中,交由TestRunner來運行。為了利用 JUnit 帶來的高效率,首先需要改變被測存儲過程的調用方式,即從手工調用改為使用 JDBC 來調用,把一個個存儲過程的調用寫成Java 代碼,以后需要進行回歸測試時,只需要運行這些 Java測試代碼就可以了。但是直接使用 JUnit,也會是一個煩瑣的過程,因為必須在每段測試代碼中編寫連接數據庫的代碼和調用存儲過程時的一大堆參數設置的代碼。對于存儲過程測試來說,這些代碼就顯得非常累贅了,于是設想把這些操作封裝為一個公用的類,只需要在測試代碼中提供數據庫連接信息、存儲過程名字和參數值就可以了,其他的工作由這個公用的類來處理。因此在實現存儲過程測試代碼的自動生成過程中,首先必須要解決如何獲得存儲過程名和存儲過程參數以及在生成的測試代碼中如何運行存儲過程,下面分別進行討論。
2.1 存儲過程名和參數的獲取
在存儲過程測試代碼生成過程中,第一個問題是要針對哪些存儲過程生成測試代碼。獲取存儲過程名可以有兩種方式,其一是由用戶手動指定,其二是將儲過程名稱保存在文件中,由系統自動從文件中分析出存儲過程名稱。這樣的文件可以是一個定義了 Java 常量的 .java 文件,也可以是一個 .properties 文件。文件中可用\"=\"來定義存儲過程,系統將自動把\"=\"右邊的部分識別為存儲過程的名稱。
要為存儲過程自動生成測試代碼,有一個前提條件是被測試的存儲過程已經在數據庫中創建。作為數據庫的對象,存儲過程的名稱、參數等信息也都有相應的數據字典表存放。只要知道存儲過程的名字,可以查詢數據字典來獲取存儲過程的參數信息,如參數名稱、數據類型、長度、出入參類型等。因此,在測試代碼生成過程中可以根據存儲過程的名稱查詢數據庫的系統表來獲取參數信息,例如DB2 的 SYSCAT.ROUTINEPARMS表,Oracle 的 USER_ARGUMENTS 表或者SQLServer的SYSCOLUMNS 表等。
2.2 測試代碼中存儲過程的運行
在已經生成的測試代碼中,如果將大批的數據庫操作寫在測試代碼中顯然是不合適的,這樣會造成代碼的混亂和維護困難。因此考慮封裝一個類,用它專門來運行存儲過程,它提供了以下主要方法:
1) SPProcesss (DBInfoObject dbConfig), 構造函數,根據傳入的數據庫配置信息,建立數據庫連接,初始化運行環境;2) getSPParmList(String routineSchema , String routineName) 根據存儲過程模式和存儲過程名獲取參數列表;3) runStoredProcedure(StoredProcedureInfo spInfo) 運行存儲過程,存儲過程信息包含在名為 StoredProcedureInfo 的類中。4) String (getDurationTime) 獲取存儲過程運行時間;5) object getReturnedObject (int parmIndex)獲取存儲過程輸出參數的值。
其中的 StoredProcedureInfo是記錄存儲過程信息的類,包括存儲過程名、存儲過程參數列表等。因此,只需要首先創建存儲過程信息,然后調用 runStoredProcedure 方法即可運行存儲過程。而這部分代碼也是自動生成的,程序員真正需要做的就是修改調用參數的值。
3 改進的Junit框架
采用Junit作為單元測試工具有許多優點,但也存在著不足。在實際的單元測試中,發現JUnit產生的測試代碼量是龐大的。為了提高測試代碼的復用,文獻[6]提出了一種改進的自動化單元測試框架。該框架設計的核心是實現測試用例與測試代碼的分離,運用XML文件作為測試數據存儲的容器,把每個測試用例中的數據裝入到對應的JavaBean中,最后構建一個JavaBean對象為元素的ArraList來存儲所有的測試用例。測試執行時,測試代碼只需要從ArrayList里面取得測試用例的數據,測試代碼僅僅完成驗證任務。這樣,如果測試用例增加了,只需修改相應的XML文件,而不必再修改測試代碼,就可完成相應的測試。
借鑒文獻[6]的方法,本文將測試用例和測試結果都存儲為 XML 文檔,使用方法writeToFile(String fileName, String time,ArrayList testResultList)將測試結果保存在XML文件中,測試結果可以包括存儲過程運行的時間、返回的記錄數、調用的參數列表或者出錯信息等。選擇把測試結果保存為 XML的一個重要原因是通過簡單的 XML編程即可實現對歷次的測試結果的比較分析。其實現方法就是將測試結果的XML文件命名為 TestCaseName_年_月_日_時_分_秒.xml,每次運行測試例后,都生成一個具有時間戳的測試結果文件,例如:
testSP_2009_10_18_17_27_00.xml
testSP_2009_10_18_17_30_00.xml
testSP_2009_10_18_17_32_00.xml
通過比較這三個文件中同一個存儲過程的運行耗時、返回記錄數等指標就能知道這次的測試結果比上次是否有所改進,或者系統在不同時間點的性能變化情況。
有了JUnit 測試代碼之后,在 Eclipse 中,左鍵雙擊將要運行的 Java 文件,選擇 Run As->JUnit Test 就可以在工作環境中運行測試文件了。運行完畢后,會生成一個XML文件,再配合以XSL樣式文件,就可以在瀏覽器中看到美觀的測試報告了。
4 結束語
Junit和Eclipse兩種軟件的源代碼都能從網上免費獲得,利用Junit基于XML存儲測試數據和測試結果的新測試框架真正提高了測試效率,簡化了測試步驟,從根本上提高了測試代碼的重用性。利用JUnit實現了以往存儲過程測試中很難進行的回歸測試,利用XML技術實現了測試數據和測試代碼分離,提高了測試效率,為開發人員提供了直觀的測試結果。
現有的測試框架可以擴展到Cactus(Apache Software開發的用來對服務器上的Java代碼進行測試的框架)框架上,實現從瀏覽器進行存儲過程測試用例的調用執行,可以克服因為開發和生產環境之間可能存在的網絡、安全等因素而影響測試準確性的問題。
參考文獻:
[1] 余波,王樹林,張大方.基于Junit自動生成類測試案例框架的實現[J].計算機工程與應用,2006,42(1):89-91.
[2] 王東剛.軟件測試與JUnit實踐[M].北京:人民郵電出版社,2004.
[3] 孔亮亮,殷兆麟.Java類測試工具Junit的分析與擴展[J].計算機工程與設計,2005,26(12):3413-3415.
[4] 何成萬,余秋惠.用JUnit實現Java程序自動測試[J].計算機應用,2002,22(3):93-94.
[5] 王聰.基于JUnit框架的軟件測試[J].湖北汽車工業學院學報,2007,21(1):43-46.
[6] 隋智泉.一種改進的單元測試JUnit框架[J].電腦知識與技術:學術交流,2007,2(8):479-480.