導(dǎo)讀:本文不討論單元測(cè)試是什么,或者它之于一個(gè)工程的利弊,我認(rèn)為單元測(cè)試是一個(gè)開發(fā)者保證產(chǎn)出代碼質(zhì)量的有效工具。本文從使用者的角度對(duì)比當(dāng)下比較流行的兩款單元測(cè)試框架,給大家提供一些選用建議。如果你還不甚了解單元測(cè)試在工程中所起到的作用,或者還不知道TDD的開發(fā)模式,可參考:Test-Driven Development和Unit Testing。 本文對(duì)比兩個(gè)iOS開發(fā)中常見的單元測(cè)試框架:OCUnit,被官方集成進(jìn)XCode 4.x版本中;GHUnit,被推薦最多的測(cè)試框架,帶GUI界面。初窺兩款測(cè)試框架非常相似,而上手使用就會(huì)發(fā)現(xiàn)其中的區(qū)別。細(xì)節(jié)上的區(qū)別使兩款框架在不同角度各有優(yōu)劣。 OCUnit OCUnit是XCode 4.x集成的單元測(cè)試框架,OCUnit中的測(cè)試分為兩類,一類稱為L(zhǎng)ogic Tests,另一類稱為Application Tests。Logic Tests更傾向于所謂的白盒測(cè)試,用于測(cè)試工程中較細(xì)節(jié)的邏輯;Application Tests更傾向于黑盒測(cè)試,或接口測(cè)試,用于測(cè)試直接與用戶交互的接口。 ·添加單元測(cè)試 OCUnit是XCode集成的,所以其與工程的結(jié)合理應(yīng)是最好的,添加到工程中的成本也理應(yīng)最低。使用XCode創(chuàng)建新工程的流程中就有一個(gè)“Include Unit Tests”的選項(xiàng)(如圖1),新的工程就會(huì)自動(dòng)生成一個(gè)Logic Tests。
向已存在的工程中添加OCUnit Logic Tests也不復(fù)雜,只需要添加一個(gè)類型為:“Cocoa Touch Unit Testing Bundle”的Target即可(如圖2)。
圖2,向已存在的工程中添加OCUnit測(cè)試 向已有工程中添加一個(gè)測(cè)試Target時(shí),XCode會(huì)自動(dòng)生成一個(gè)Scheme,運(yùn)行單元測(cè)試用例和Build原工程需要切換不同的Scheme。如果認(rèn)為切換Scheme非常麻煩,也可以在添加Target之前,在“Manage Scheme”菜單中取消“Autocreate schemes”(如圖3)。
圖3,添加Target不創(chuàng)建Scheme Application Tests要基于Logic Tests做一些修改。一般來(lái)說(shuō)一個(gè)工程既需要Logic Tests也需要Application Tests,所以建議按照上述方法添加一個(gè)單獨(dú)的Target,然后執(zhí)行以下操作(如圖4): 1. 在Build Settings中搜索“bundle loader”,設(shè)置為:$(BUILT_PRODUCTS_DIR)/APP_NAME.app/APP_NAME(APP_NAME是應(yīng)用名) 2. 再搜索“test host”,設(shè)置為:$(BUNDLE_LOADER) 3. 在Build Phases-Target Dependencies中添加依賴,選擇主程序Target
圖4,添加一個(gè)Application Tests ·創(chuàng)建測(cè)試用例 OCUnit的測(cè)試用例最常用的方法有三個(gè) 1. - (void)setUp:每個(gè)test方法執(zhí)行前調(diào)用 2. - (void)tearDown:每個(gè)test方法執(zhí)行后調(diào)用 3. - (void)testXXX:命名為XXX的測(cè)試方法 添加Target之時(shí)XCode已經(jīng)自動(dòng)創(chuàng)建了一個(gè)測(cè)試用例類:UnitTestDemoTests,其中UnitTestDemo是工程的名字,該類中已經(jīng)包含了setUp,tearDown和testExample三個(gè)方法。 通過(guò)command+n,選擇“Objective-C test case class”創(chuàng)建一個(gè)新的測(cè)試用例類(如圖5)。通過(guò)XCode創(chuàng)建的測(cè)試用例類是一個(gè)繼承自SenTestCase(OCUnit由SEN:TE公司開發(fā),因此基類命名為SenTestCase)的空類,需要模仿UnitTestDemoTests編寫測(cè)試方法。
圖5,創(chuàng)建一個(gè)測(cè)試用例類 開發(fā)者可以自己實(shí)現(xiàn)無(wú)返回值,且命名規(guī)則為testXXX的實(shí)例方法,并使用框架提供的大量斷言方法。 Logic Tests與Application Tests的區(qū)別主要在setUp方法,Logic Tests只需在setUp方法中初始化一些測(cè)試數(shù)據(jù),而Application Tests需要在setUp方法中獲取主應(yīng)用的AppDelegate,供test方法調(diào)用。 值得注意的是,OCUnit的test bundle是侵入主應(yīng)用的,因此在使用過(guò)程中要十分注意,不要讓單元測(cè)試的資源覆蓋主應(yīng)用資源,造成詭異的Bug。 ·運(yùn)行測(cè)試 由于OCUnit是集成在XCode中的框架,因此在XCode中運(yùn)行也比較方便。切換到單元測(cè)試的scheme(如果與工程共用scheme則無(wú)需切換),Product->Test(或直接使用快捷鍵command+u),框架會(huì)自動(dòng)查找所有工程中SenTestCase的子類,運(yùn)行其中全部命名類似testXXX的無(wú)返回值方法。 ·測(cè)試反饋 OCUnit的失敗方法會(huì)通過(guò)Console和XCode Issues兩個(gè)位置反饋,通過(guò)XCode Issues可以直接定位到出現(xiàn)錯(cuò)誤的單元測(cè)試代碼行。Issue的提示信息就是在單元測(cè)試斷言方法中定義的description。 GHUnit GHUnit是一款Objective-C的測(cè)試框架,除了支持iOS工程還支持OSX的工程,但OSX不在本文的討論范圍。GHUnit不同于OCUnit,它提供了GUI界面來(lái)操作測(cè)試用例,而且也不區(qū)分Logic Tests和Application Tests。 ·添加單元測(cè)試 與集成進(jìn)XCode的OCUnit相比,GHUnit的添加過(guò)程略顯復(fù)雜。首先在上下載GHUnit的框架包,當(dāng)前的For iOS的最新版本是0.5.6,解壓后是一個(gè)GHUnitIOS.framework的文件夾。 打開已經(jīng)存在的工程,添加一個(gè)EmptyApplication Target,并在新Target中添加剛剛下載的GHUnitIOS.framework(如圖6、7)。
圖6,在新Target中添加GHUnitIOS.framework 在Build Phases中添加非官方框架并不會(huì)把框架文件拷貝到工程目錄,而是只做一個(gè)鏈接,所以建議在添加之前先把框架拷貝到工程目錄下。
圖7,選擇GHUnitIOS.framework 接下來(lái)用相同的方法添加框架依賴的其他庫(kù):“QuartzCore.framework”。 在Build Settings中搜索“l(fā)inker flags”,設(shè)置Other Linker Flags - Debug - 添加一個(gè)支持全架構(gòu)和全版本SDK的標(biāo)示“-ObjC -all_load”(如圖8)。
圖8,設(shè)置linker flags 刪除Tests Target中的AppDelegate(.h和.m一起刪除)。修改main函數(shù),支持GHUnitIOS,導(dǎo)入GHUnitIOSAppDelegate代替原來(lái)的AppDelegate,修改UIApplicationMain的參數(shù)(如圖9)。
圖9,修改main函數(shù) 至此已經(jīng)完成了GHUnit的添加,選擇新建Target同時(shí)創(chuàng)建的scheme,直接Build and Run即可在設(shè)備或Simulator中啟動(dòng)一個(gè)新的App(如圖10),即該單元測(cè)試的App。
圖10,單元測(cè)試App ·創(chuàng)建測(cè)試用例 創(chuàng)建GHUnit測(cè)試用例與創(chuàng)建OCUnit測(cè)試用例相似。 新建一個(gè)Objective-C Class文件,繼承自GHTestCase,在XCode生成的.h文件中不會(huì)導(dǎo)入GHUnit.h文件,需要開發(fā)者自行導(dǎo)入“#import <GHUnitIOS/GHUnit.h>”。 GHUnit框架提供斷言方法比OCUnit更加豐富,開發(fā)用例也就可以做的更加細(xì)致,更有利查找/定位錯(cuò)誤。 測(cè)試方法的命名規(guī)則與OCUnit一樣,是以test開頭的無(wú)返回值方法:- (void)testXXX。而常用的方法除了上述提到的setUp和tearDown,GHUnit還提供了setUpClass和tearDownClass兩個(gè)方法,在該用例運(yùn)行前和結(jié)束后調(diào)用。另外,剛剛提到GHUnit不區(qū)分Logic Tests和Application Tests,所以在setUp和tearDown方法中也就不存在設(shè)置的區(qū)分。 ·運(yùn)行測(cè)試 運(yùn)行GHUnit需要分兩步,首先編譯并安裝單元測(cè)試App到設(shè)備或Simulator里(如圖11),創(chuàng)建了兩個(gè)用例,每個(gè)用例中分別有一個(gè)方法。
圖11,兩個(gè)用例的GHUnit App 在App中可以通過(guò)點(diǎn)擊右上角的Run按鈕運(yùn)行全部用例,框架會(huì)查找所有以testXXX命名的無(wú)返回值方法,并執(zhí)行?;螯c(diǎn)擊TableView中的某個(gè)Cell運(yùn)行單獨(dú)的測(cè)試方法。 ·測(cè)試反饋 斷言失敗測(cè)試未通過(guò)的方法在App中會(huì)標(biāo)記為紅色,并給出每一個(gè)方法的運(yùn)行時(shí)間。在Console中會(huì)打印出詳細(xì)的出錯(cuò)信息,包括:異常類型,出錯(cuò)文件,位置,以及斷言方法中指定的出錯(cuò)原因。更重要的是,出錯(cuò)時(shí)的程序堆棧內(nèi)容(如圖12)。
圖12,未通過(guò)測(cè)試的方法,Console中的內(nèi)容 GHUnit通過(guò)Console中的內(nèi)容給開發(fā)者提供幫助,可以快速定位程序出錯(cuò)的位置,這一點(diǎn)比OCUnit做的要好。 總結(jié) GHUnit在安裝上確實(shí)顯得有些麻煩,無(wú)法跟集成在XCode里的OCUnit相比。 但從開發(fā)者的角度講,我更喜歡GHUnit帶來(lái)的體驗(yàn),GUI的操作界面可以脫離IDE單獨(dú)運(yùn)行,支持運(yùn)行單一測(cè)試方法和運(yùn)行全部用例的,打印出錯(cuò)堆??梢愿於ㄎ坏絾?wèn)題所在。 本文簡(jiǎn)單介紹了兩款框架的安裝與入門,可以初步了解其各自特點(diǎn),在接下來(lái)的文章中將會(huì)更加詳細(xì)的介紹如何使用框架進(jìn)行單元測(cè)試,以及框架中的一些高級(jí)功能。此外,后續(xù)還將向大家介紹另外的與這兩款框架區(qū)別更加明顯的單元測(cè)試框架。 標(biāo)簽:
軟件測(cè)試培訓(xùn) 軟件測(cè)試教程 單元測(cè)試 軟件測(cè)試工程師
|
|
來(lái)自: 現(xiàn)在決定明天 > 《代碼人生》