一、什么是UnitTest
在Xcode的API中這樣描寫:
The XCTest framework enables you to write unit tests for your Xcode projects that integrate seamlessly with the Xcode testing workflow, as described in Testing with Xcode.
Tests assert that certain conditions are satisfied during test execution, and record test failures (with optional messages) if those conditions are not satisfied. Tests can also measure the performance of blocks of code to check for performance regressions, and can interact with an application's UI to validate user interaction flows.
總結(jié)來說就是針對代碼模塊:1、測試代碼是否滿足某些條件,如果不滿足,則記錄失?。?、測試代碼模塊性能(測試代碼執(zhí)行花費(fèi)的時(shí)間);3、驗(yàn)證UI交互(這部分屬于UITest暫且不討論,實(shí)用性太差)
二、什么時(shí)候使用UnitTest
iOS UnitTest最大的好處是,我們可以不運(yùn)行我們的工程而測試我們想要測試的代碼,并且可以做到批量測試,對于APP來講,我們可以就免去了多個(gè)頁面的點(diǎn)擊,以及覆蓋問題。最明顯的就是接口測試,我們可以可以做到一鍵測試所有接口(事實(shí)上并不是真的一鍵,我們還是需要配置每個(gè)需要測試的接口,但是一次配置,就可以做到一勞永逸)是否完好。在我們的接口改變,新增等情況下,我們不但需要對新增的接口測試,還需要查看老接口是否受影響的情況下,UnitTest就顯示十分方便。
對于接口測試,屬于我們前文所提到的“測試代碼是否滿足某些條件”,這個(gè)方法還可以檢查我們的代碼邏輯,譬如我們工程里有本地計(jì)算訂單費(fèi)用,積分等,都可以用這個(gè)思想進(jìn)行測試。
測試代碼模塊性能:我們可以用以測試代碼運(yùn)行花費(fèi)時(shí)間,block執(zhí)行時(shí)間。當(dāng)我們有下載需求,比如捕手中的二維碼保存,可以大致打估出所需時(shí)間(不太實(shí)用,對下載最大影響還是網(wǎng)速)。
三、UnitTest的使用
1、創(chuàng)建
第一個(gè)方法是在創(chuàng)建工程時(shí)勾選Include Unit Test

或者在創(chuàng)建工程以后,再添加target

這時(shí)候,我們可以看到工程里多了一個(gè)Tests文件夾,里面包含一個(gè)一個(gè)Test文件,

這就是我們的unitTest文件,當(dāng)然,我們也可以自己再創(chuàng)建多個(gè),以此來區(qū)分測試不同的模塊。
可以看到.m文件初始包含4個(gè)方法
1)setUp:所有測試方法執(zhí)行之前都會(huì)執(zhí)行這個(gè)方法,如果我們需要確定一個(gè)對象的方法,可現(xiàn)在這個(gè)方法里實(shí)例化對象。
2)tearDown:所有測試方法執(zhí)行之后都會(huì)執(zhí)行這個(gè)方法
3)testExample:一個(gè)測試用例,里面可以寫測試代碼,我們自己寫測試方法,都以test開頭,才會(huì)有自動(dòng)執(zhí)行
4)testPerformanceExample:里面的measureBlock內(nèi)為性能測試,測試一段代碼執(zhí)行時(shí)常。
2、使用
我們先來看XCTest自帶的斷言:
XCTAssertNotNil(a1, format…) 當(dāng)a1不為nil時(shí)成立
XCTAssert(expression, format...) 當(dāng)expression結(jié)果為YES成立
XCTAssertTrue(expression, format...) 當(dāng)expression結(jié)果為YES成立;
XCTAssertEqualObjects(a1, a2, format...) 判斷相等,當(dāng)[a1 isEqualTo: a2]返回YES的時(shí)候成立
XCTAssertEqual(a1, a2, format...) 當(dāng)a1==a2返回YES時(shí)成立
XCTAssertNotEqual(a1, a2, format...) 當(dāng)a1!=a2返回YES時(shí)成立
&&
XCTFail(format…) 生成一個(gè)失敗的測試;
XCTAssertNil(a1, format...)為空判斷,a1為空時(shí)通過,反之不通過;
XCTAssertNotNil(a1, format…)不為空判斷,a1不為空時(shí)通過,反之不通過;
XCTAssert(expression, format...)當(dāng)expression求值為TRUE時(shí)通過;
XCTAssertTrue(expression, format...)當(dāng)expression求值為TRUE時(shí)通過;
XCTAssertFalse(expression, format...)當(dāng)expression求值為False時(shí)通過;
XCTAssertEqualObjects(a1, a2, format...)判斷相等,[a1 isEqual:a2]值為TRUE時(shí)通過,其中一個(gè)不為空時(shí),不通過;
XCTAssertNotEqualObjects(a1, a2, format...)判斷不等,[a1 isEqual:a2]值為False時(shí)通過;
XCTAssertEqual(a1, a2, format...)判斷相等(當(dāng)a1和a2是 C語言標(biāo)量、結(jié)構(gòu)體或聯(lián)合體時(shí)使用, 判斷的是變量的地址,如果地址相同則返回TRUE,否則返回NO);
XCTAssertNotEqual(a1, a2, format...)判斷不等(當(dāng)a1和a2是 C語言標(biāo)量、結(jié)構(gòu)體或聯(lián)合體時(shí)使用);
XCTAssertEqualWithAccuracy(a1, a2, accuracy, format...)判斷相等,(double或float類型)提供一個(gè)誤差范圍,當(dāng)在誤差范圍(+/-accuracy)以內(nèi)相等時(shí)通過測試;
XCTAssertNotEqualWithAccuracy(a1, a2, accuracy, format...) 判斷不等,(double或float類型)提供一個(gè)誤差范圍,當(dāng)在誤差范圍以內(nèi)不等時(shí)通過測試;
XCTAssertThrows(expression, format...)異常測試,當(dāng)expression發(fā)生異常時(shí)通過;反之不通過;(很變態(tài)) XCTAssertThrowsSpecific(expression, specificException, format...) 異常測試,當(dāng)expression發(fā)生specificException異常時(shí)通過;反之發(fā)生其他異?;虿话l(fā)生異常均不通過;
XCTAssertThrowsSpecificNamed(expression, specificException, exception_name, format...)異常測試,當(dāng)expression發(fā)生具體異常、具體異常名稱的異常時(shí)通過測試,反之不通過;
XCTAssertNoThrow(expression, format…)異常測試,當(dāng)expression沒有發(fā)生異常時(shí)通過測試;
XCTAssertNoThrowSpecific(expression, specificException, format...)異常測試,當(dāng)expression沒有發(fā)生具體異常、具體異常名稱的異常時(shí)通過測試,反之不通過;
XCTAssertNoThrowSpecificNamed(expression, specificException, exception_name, format...)異常測試,當(dāng)expression沒有發(fā)生具體異常、具體異常名稱的異常時(shí)通過測試,反之不通過
用一個(gè)XCTAssertTrue舉例來說,可以看出這個(gè)函數(shù)是判斷是否為真。比如我們做出XCTAssertTrue(3>5)的判斷,為結(jié)果正確,測試會(huì)順利通過,假如XCTAssertTrue(3>5),結(jié)果為假,便會(huì)報(bào)錯(cuò),并展示我們所添加說明。我們可以寫一段代碼測試一下:

在以test開頭的方法左邊,我們可以看到一個(gè)菱形的標(biāo)志,點(diǎn)擊就可以運(yùn)行這段測試代碼,也可以command + U執(zhí)行所有測試代碼,還可以如圖所示,點(diǎn)擊工程右邊的執(zhí)行鍵,或者模塊的,或者指定方法的:



運(yùn)行結(jié)果:

報(bào)錯(cuò)了,如果我們執(zhí)行了所有測試代碼,這時(shí)候我們可以在Xcode界面里看到所有的測試代碼的運(yùn)行加過,成功的會(huì)有對號(hào),錯(cuò)誤的會(huì)報(bào)錯(cuò),錯(cuò)誤的測試代碼并會(huì)不影響其他的方法,這樣我們可以方便的查看所有出問題的代碼,如下圖所示。

接著看上面這張圖,可以看到我在setUp方法里,實(shí)例化了一個(gè)ViewController。我在ViewController寫了一個(gè)簡單的A-B求值的方法,我們可以寫在XCTAssertTrue里測試:

我們接著看上面的大圖,可以看到下面的testExample方法,我們進(jìn)行了網(wǎng)絡(luò)請求的測試。
在這里,測試方法是異步執(zhí)行,我們可以設(shè)置期望,來設(shè)定我們期望的時(shí)間。

我們在創(chuàng)建expectation時(shí),可以加入錯(cuò)誤描述,比如我們這個(gè)網(wǎng)絡(luò)請求,我在waitForExpectationsWithTimeout設(shè)置了時(shí)間為3,在expectationWithDescription設(shè)定的問題描述是超時(shí),當(dāng)我們的這個(gè)網(wǎng)絡(luò)請求超過3秒鐘,在waitForExpectationsWithTimeout就會(huì)報(bào)錯(cuò),錯(cuò)誤描述就會(huì)有我們的問題描述,在看我請求成功里寫的,XCTAssertNotNil(responseObject, @“返回出錯(cuò)”),XCTAssertNotNil判斷里面的對象不為nil,如果是nil則報(bào)錯(cuò),展示返回錯(cuò)誤。參考:XCTest的waitForExpectationsWithTimeout 方法
接下來我們看下面這個(gè)方法

描述為性能測試,我們可以把自己需要測試的方法放到block里,block里的代碼,會(huì)執(zhí)行10次,取出平均值,比如我們在這里打印1000次,點(diǎn)擊旁邊的菱形運(yùn)行

我們可以看到,右邊的測試結(jié)果展示了這段代碼執(zhí)行所用的時(shí)間,這是簡單應(yīng)用,我們可以測試ViewController的代碼性能。
接下來點(diǎn)擊左邊的灰色菱形,在這里可以看到這十次執(zhí)行的每次執(zhí)行時(shí)間,

在這里我們點(diǎn)擊set Baseline 可以設(shè)定我們的逾期,
比如我們設(shè)定逾期時(shí)間為 0.100S

然后執(zhí)行這段代碼,

可以看到,報(bào)錯(cuò)了,并且告訴我們,這段打碼執(zhí)行時(shí)間超出了我們超出的程度。
參考資料:http://blog.csdn.net/jeikerxiao/article/details/51668655