沈雷 楊竣鐸
摘要:隨著國產(chǎn)化工作的推進(jìn),國產(chǎn)生態(tài)環(huán)境日益成熟,運行于國產(chǎn)平臺的軟件數(shù)量不斷增加,對測試工具的需求也越來越高。文章對國產(chǎn)計算機(jī)系統(tǒng)的開源測試工具進(jìn)行研究,從靜態(tài)分析、單元測試、功能測試、性能測試和覆蓋測試對工具進(jìn)行了分類,提出了國產(chǎn)操作系統(tǒng)開源測試工具整合方案。
關(guān)鍵詞:國產(chǎn)化;開源工具;軟件測試
中圖分類號:TP311 文獻(xiàn)標(biāo)識碼:A 文章編號:1007-9416(2020)08-0080-03
0 引言
經(jīng)過多年發(fā)展,開源軟件運動已經(jīng)獲得很大成功,借助開源測試工具構(gòu)造一個完整的測試解決方案,既能提高測試效率又能降低測試成本。另一方面,國產(chǎn)操作系統(tǒng)雖愈來愈成熟,但缺乏基于這些操作系統(tǒng)的軟件測試方法。我們希望能夠把現(xiàn)有的較為成熟的開源軟件測試工具進(jìn)行整合,形成一個能穩(wěn)定運行于國產(chǎn)操作系統(tǒng)的軟件測試解決方案。該方案能應(yīng)用于靜態(tài)分析、單元測試、功能測試、性能測試和覆蓋測試等測試常用場景。
與商業(yè)軟件測試工具相比,開源軟件測試工具具有如下特點:
(1)數(shù)量大:僅在opensourcetesting.org網(wǎng)站上統(tǒng)計的開源軟件測試工具就有超過360種,其中面向Java程序的單元測試開源軟件工具就有70多種。
(2)目標(biāo)單一:開源軟件測試工具往往是面向一個非常具體的領(lǐng)域,而不像商業(yè)軟件測試工具會將各種功能模塊集成起來,解決各個領(lǐng)域的問題。例如,每種開源的軟件單元測試工具往往只能支持一種開發(fā)語言。
(3)運行需求各異:不同的開源軟件測試工具有不同的運行需求,包括不同的操作系統(tǒng)版本、不同的腳本語言版本(如不同版本的waitr需要先安裝不同版本的Ruby)。
(4)用戶使用不便:很多開源軟件測試工具都缺乏良好的用戶使用界面,也缺乏穩(wěn)定的維護(hù)團(tuán)隊。
這些特點決定了將開源測試工具整合起來并不容易。在后面的討論中,我們按照單元測試、功能測試、性能測試的順序推薦了一些較為成熟、使用較為廣泛的開源軟件測試工具。要說明的是,考慮到廣泛使用的國產(chǎn)操作系統(tǒng)一般都是基于Linux或類似產(chǎn)品開發(fā)的,本文中只討論能基于Linux使用的開源測試工具。同時考慮到目前國產(chǎn)操作系統(tǒng)上較常使用的開發(fā)環(huán)境,本文中重點討論針對Java、C和C++的開源測試工具。
1 單元測試
單元測試(unit testing)中,軟件的獨立單元將在與程序的其他部分相隔離的情況下進(jìn)行測試。對于單元測試,使用最多的是基于XUnit框架的測試用例設(shè)計方法。
1.1 XUnit
XUnit是一個基于測試驅(qū)動開發(fā)的測試框架體系,為用戶在開發(fā)過程中使用測試驅(qū)動開發(fā)提供了一個方便的工具。根據(jù)被測軟件使用的開發(fā)語言的不同,XUnit的成員有很多,如JUnit、CUnit、CPPUnit、PythonUnit、PHPUnit、SQLUnit等,其中每個測試框架都有開源的安裝包。這里我們重點討論JUnit、CUnit和CPPUnit。
1.1.1 JUnit
Junit是單元測試框架體系XUnit的一個實例,也是該框架體系中最為成功的一個。通常使用JUnit進(jìn)行測試的基本流程如下:
(1)創(chuàng)建一個TestCase的子類;
(2)寫一個測試方法斷言期望的結(jié)果;
(3)寫一個suite()方法,創(chuàng)建一個包含全部testxxx方法的測試套件;
(4)寫一個main()方法以運行測試;
1.1.2 CUnit
CUnit是一種C語言單元測試框架,使用CUnit進(jìn)行測試的基本流程如下:
(1)書寫待測試的函數(shù)(如果必要,需要寫suite的init/cleanup函數(shù));
(2)初始化Test Registry-CU_initialize_registry();
(3)把測試包(Test Suites)加入到Test Registry - CU_add_suite();
(4)加入測試用例(Test Case)到測試包當(dāng)中-CU_add _test();
(5)使用適當(dāng)?shù)慕涌趤磉\行測試程序,例如CU_co-nsole_run_tests();
(6)清除Test Registry-CU_cleanup_registry()。
1.1.3 CPPUnit
CPPUnit是XUnit框架針對C++語言的實現(xiàn)。使用CPPUnit進(jìn)行測試的基本流程如下:
(1)初始化操作,包括:生成被測試的對象及其初始化值;
(2)按照要測試的功能或者流程對測試對象進(jìn)行操作;
(3)對結(jié)果進(jìn)行驗證;
(4)測試資源的釋放清理。
1.2 其他工具
1.2.1 對JUnit的擴(kuò)展
一些開發(fā)者基于JUnit進(jìn)行了一些擴(kuò)展,增強(qiáng)了該框架的能力。例如,Cactus專門用于對服務(wù)端的Java代碼單元測試(Servlets、EJBs、Tag Libs、Filters、...),DbUnit專門用于對數(shù)據(jù)庫驅(qū)動項目的Java代碼單元測試。
1.2.2 Check
Check是另一種對C語言進(jìn)行單元測試的測試框架,最主要的優(yōu)點是對于每一個測試用例的運行都fork一個子進(jìn)程,這么做的原因是因為C語言的獨特性:其他語言如Java,Python,Ruby等,單元測試運行出錯時最多不過是拋出異常,而C語言如果指針操作錯誤,會遇到“coredump”問題,測試框架直接退出,用戶看不到任何返回。Check的單元測試運行在fork子進(jìn)程中,可以避免測試框架由于“coredump”而崩潰,優(yōu)點顯而易見。
1.2.3 CxxTest
CxxTest采用Perl分析C++源文件,從中抽取測試元素,創(chuàng)建用例。由于不需要編寫額外的代碼,增添新的測試工作量小,可移植性好。編譯即測試是其最大的優(yōu)點。
2 測試覆蓋率統(tǒng)計
很多測試項目對測試覆蓋率提出了明確的要求,因此對測試用例集的測試覆蓋率統(tǒng)計有著很大的現(xiàn)實意義。根據(jù)被測軟件使用的不同開發(fā)語言,已經(jīng)存在多種開源測試工具,下面討論幾個常用的工具。
2.1 Emma & EclEmma
Emma是JAVA代碼覆蓋率的開源工具,支持包,類,方法,語句塊(basic block)和行等多級別的覆蓋率指標(biāo):能測出某一行是否只是被部分覆蓋,如條件語句短路的情況。Emma能和Makefile和Ant集成,且執(zhí)行效率高,適用于大型項目。
EclEmma是Eclipse和Emma兩個工具的結(jié)合,增加了圖形界面以及對集成開發(fā)環(huán)境的支持,便于用戶使用。
2.2 gcov & lcov
gcov是C/C++軟件的測試代碼覆蓋率的工具,配合GCC共同實現(xiàn)對C/C++文件的語句覆蓋和分支覆蓋測試;結(jié)合程序概要分析工具(profiling tool,例如gprof),gcov可以統(tǒng)計每一行代碼的執(zhí)行頻率、覆蓋情況及耗時(執(zhí)行時間)。
lcov是gcov圖形化的前端工具,是LTP(Linux Test Project)維護(hù)的開放源代碼工具,最初被設(shè)計用來支持Linux內(nèi)核覆蓋率的度量。lcov基于Html輸出并生成一棵完整的HTML樹,包括概述、覆蓋率百分比、圖表,能快速瀏覽覆蓋率數(shù)據(jù)。lcov支持大項目,提供三個級別的視圖:目錄視圖、文件視圖、源碼視圖。
3 代碼靜態(tài)檢查
代碼靜態(tài)檢查是指通過分析或檢查源程序的語法、結(jié)構(gòu)、過程、接口等來檢查程序的正確性,找出代碼隱藏的錯誤和缺陷,如參數(shù)不匹配、可能出現(xiàn)的空指針引用等。
3.1 Findbugs
FindBugs是一款開源Java靜態(tài)代碼分析工具。它通過檢查類文件或JAR文件,將字節(jié)碼與一組缺陷模式進(jìn)行對比從而發(fā)現(xiàn)代碼缺陷。在工具界面,需要先選擇待掃描的 .class文件。如果有這些.class檔對應(yīng)的源文件,可把這些 .java文件再選上,這樣便可以從稍后得出的報告中快捷定位到出問題的代碼。此外,還可以選擇工程所使用的庫,這樣可以幫助FindBugs做一些高階的檢查,發(fā)現(xiàn)一些更深層的缺陷。可以發(fā)現(xiàn)的典型缺陷如空指針引用、特定的資源未關(guān)閉、多余的If后置條件、錯誤地使用了“==”等等。
3.2 Splint
splint是一個靜態(tài)檢查C語言程序安全弱點和編寫錯誤的靜態(tài)測試工具,不需要運行程序即可進(jìn)行錯誤檢查,包括未使用的變量、類型不一致、使用未定義變量、無法執(zhí)行的代碼、忽略返回值、執(zhí)行路徑未返回、無限循環(huán)等錯誤。能通過splint的輸出結(jié)果,分析出被測C語言程序中的錯誤所在,并實現(xiàn)錯誤在程序中的定位。
4 功能測試
功能測試是按功能需求對軟件進(jìn)行的測試,也叫黑盒測試或數(shù)據(jù)驅(qū)動測試。面向功能測試的測試工具的主要任務(wù)是快速生成正確的測試用例。
4.1 Abbot
Abbot是一個用來測試JavaGUIs的框架。Abbot提供了一組API可以允許開發(fā)抓取應(yīng)用程序窗口中的各個組件,然后模擬用戶的操作。Abbot提供了錄制腳本的功能,可以利用錄制工具在配置好相關(guān)應(yīng)用的Jar包的類和函數(shù)后,啟動應(yīng)用并錄制相關(guān)腳本。錄制的腳本可以導(dǎo)出為xml格式的文件。也可以在腳本中添加斷言來給自動化腳本添加一些業(yè)務(wù)邏輯的判斷和控制。目前我們使用Abbot更多是用來做組件的功能測試,也可以理解為是一個對于組件的單元測試框架,可以繼承到Junit或者是Fitnesse框架中。
4.2 Marathon
Marathon是一個基于Jython的開源自動化GUI測試框架。Marathon的錄制功能比較強(qiáng)大,而且操作界面比較直觀,方便使用。Mathon錄制的腳本是基于Jython的,由于Jython是運行在JVM上面的Python,語法也和Java比較接近,對于有java經(jīng)驗的工程師而言,非常容易上手。Marathon提供的fixture和module功能,可以把自動化腳本模塊化,提高了腳本的復(fù)用性。
4.3 Selenium(Selenium WebDriver)
Selenium是用于Web應(yīng)用程序的一個開源測試工具,直接運行在瀏覽器中??梢栽赪indows、Linux和Mac上的 Internet Explorer、Mozilla和Firefox瀏覽器中運行。主要功能包括:(1)測試應(yīng)用程序與瀏覽器的兼容性;(2)測試系統(tǒng)功能,包括創(chuàng)建衰退測試檢驗軟件功能和用戶需求。支持自動錄制,可以自動生成.Net、Java、Perl等不同語言的測試腳本。
5 性能測試
性能測試是通過測試工具模擬各種正常、峰值以及異常負(fù)載條件來對系統(tǒng)的各項性能指標(biāo)進(jìn)行測試。負(fù)載測試和壓力測試都屬于性能測試。
5.1 JMeter
JMeter是Apache組織開發(fā)的基于Java的性能測試工具,可用于測試靜態(tài)和動態(tài)資源,包括靜態(tài)文件、Java小服務(wù)程序、CGI腳本、Java對象、數(shù)據(jù)庫、FTP服務(wù)器等等。能夠模擬負(fù)載,在不同壓力下對服務(wù)器、網(wǎng)絡(luò)或?qū)ο蟮膹?qiáng)度進(jìn)行測試并對整體性能進(jìn)行分析。
5.2 DBMonster
DBMonster是一個用生成隨機(jī)數(shù)據(jù)來測試SQL數(shù)據(jù)庫的性能測試工具。DBMonster是一個Java的開源項目,通過JDBC方式連接數(shù)據(jù)庫,可以在任何支持Java和JDBC的平臺上運行。DBMonster開發(fā)的初衷是為數(shù)據(jù)庫開發(fā)者服務(wù),可以協(xié)助產(chǎn)生大量規(guī)則或不規(guī)則數(shù)據(jù),便于數(shù)據(jù)庫開發(fā)者基于這些數(shù)據(jù)進(jìn)行數(shù)據(jù)庫的調(diào)優(yōu)。DBMonster通過兩個XML文件(配置文件和 schema文件)控制數(shù)據(jù)產(chǎn)生的行為,配置文件指明需要連接的數(shù)據(jù)庫、連接使用的用戶名和口令、需要操作的scheme、重試次數(shù)等全局設(shè)置,而 scheme文件則指明針對每張數(shù)據(jù)表的每個字段產(chǎn)生數(shù)據(jù)的規(guī)則。
6 結(jié)語
本文總結(jié)了部分常用的開源測試工具,將這些工具整合起來,可以有效地在國產(chǎn)操作系統(tǒng)基礎(chǔ)上對Java、C、C++的軟件產(chǎn)品進(jìn)行各種類型的軟件測試。在開源世界中,還有大量各具特色的開源測試工具,在使用過程中應(yīng)根據(jù)項目的特點有針對性地進(jìn)行選擇。