基于測試驅(qū)動(dòng)的iOS開發(fā)

第一次接觸基于測試驅(qū)動(dòng)的iOS開發(fā)應(yīng)該是2013年11月那會(huì)了。時(shí)間過得真快,現(xiàn)在都快三年了。那會(huì)Xcode版本還是4.6,單元測試用的OCUnit框架,自從XCode 5之后就變成了XCTest了,Xocde 7 之后又有了UI Testing的測試了,蘋果的測試真是玩的越來越666了。主要的iOS單元測試框架有XCTest,GHUnit,OCMock等。果然,大學(xué)里學(xué)的軟件測試專業(yè)課還是很有用處的,記得當(dāng)時(shí)老師講的最深刻的還是基于Socket的網(wǎng)絡(luò)編程,一大堆基于測試用例的條件編寫的白盒測試。黑盒測試,系統(tǒng)測試,回歸測試等等。。。

UI Tests是一個(gè)自動(dòng)測試UI與交互的Testing組件。它可以通過編寫代碼、或是記錄開發(fā)者的操作過程并代碼化,來實(shí)現(xiàn)自動(dòng)點(diǎn)擊某個(gè)按鈕、視圖,或者自動(dòng)輸入文字校驗(yàn)等功能。

在實(shí)際的開發(fā)過程中,隨著項(xiàng)目越做越大,功能越來越多,僅僅靠人工操作的方式來覆蓋所有測試用例是非常困難的,尤其是加入新功能以后,舊功能也要重新測試一遍,這導(dǎo)致了測試需要花非常多的時(shí)間來進(jìn)行回歸測試,這時(shí)就產(chǎn)生了大量重復(fù)的工作,也會(huì)導(dǎo)致上線時(shí)間的耽擱。而這些重復(fù)的工作有些是可以自動(dòng)完成的,這時(shí)候UI Tests就可以幫助解決這個(gè)問題了。

而自動(dòng)化的測試框架,在Android平臺(tái)有較為成熟的Monkey工具,iOS平臺(tái)就顯得有點(diǎn)雞肋了。自打Xcode7加入了UI Testing的框架,iOS的自動(dòng)化測試才有了一片光明。Instrument工具有一項(xiàng)UIAutomation,通過結(jié)合Javascript腳本和Accessibility來推進(jìn)自動(dòng)化的步伐。自動(dòng)生成測試時(shí),先選擇測試文件后,在調(diào)試區(qū)域點(diǎn)擊錄制按鈕,就是一個(gè)小紅圓點(diǎn),這時(shí)候開始進(jìn)行操作,它會(huì)記錄你的操作步驟,并生成測試代碼。這時(shí)候可以分析測試代碼的語法,以便你自己手動(dòng)修改或者手寫測試代碼

單元測試的魅力

1.她能讓你更自信。幫助你編寫高質(zhì)量代碼、減少bug。
如果大家分析一下我們bug原因的構(gòu)成,我想有會(huì)有一部分bug的原因是開發(fā)人員在編寫工作代碼的時(shí)候沒有考慮到某些case或者邊際條件。造成這種問題的原因很多,其中很重要的一個(gè)原因是我們對工作代碼所要完成的功能思考不足,而編寫單元測試,特別是先寫單元測試再寫工作代碼就可以幫助開發(fā)人員思考編寫的代碼到底要實(shí)現(xiàn)哪些功能。例如實(shí)現(xiàn)一個(gè)簡單的用戶注冊功能的業(yè)務(wù)類方法,用單元測試再寫工作代碼的方式來工作的話開發(fā)人員就會(huì)先考慮各種場景相關(guān),例如正常注冊、用戶名重復(fù)、沒有滿足必要的填寫內(nèi)容......等等,之后就會(huì)編寫相關(guān)的測試用例。編寫單元測試代碼的過程就是促使開發(fā)人員思考工作代碼實(shí)現(xiàn)內(nèi)容和邏輯的過程,之后實(shí)現(xiàn)工作代碼的時(shí)候,開發(fā)人員思路會(huì)更清晰,實(shí)現(xiàn)代碼的質(zhì)量也會(huì)有相應(yīng)的提升。

2.她能提提升你的戰(zhàn)斗力。幫助你提升代碼的反饋速度,減少重復(fù)工作,提高開發(fā)效率。
開發(fā)人員實(shí)現(xiàn)某個(gè)功能或者修補(bǔ)了某個(gè)bug,如果有相應(yīng)的單元測試支持的話,開發(fā)人員可以馬上通過運(yùn)行單元測試來驗(yàn)證之前完成的代碼是否正確,而不需要反復(fù)通過編譯運(yùn)行simulator、等待應(yīng)用啟動(dòng)、通過輸入數(shù)據(jù)等繁瑣的步驟來驗(yàn)證所完成的功能。用單元測試代碼來驗(yàn)證代碼和通過發(fā)布應(yīng)用以人工的方式來驗(yàn)證代碼這兩者的效率差很多,所以單元測試其實(shí)還能節(jié)約人力成本。

3.她的存在讓你輕松愉快。保證你最后的代碼修改不會(huì)破壞之前代碼的功能。
項(xiàng)目越做越大,代碼越來越多,特別涉及到一些公用接口之類的代碼或是底層的基礎(chǔ)庫,誰也不敢保證這次修改的代碼不會(huì)破壞之前的功能,所以與此相關(guān)的需求會(huì)被擱置或推遲,由于不敢改進(jìn)代碼,代碼也變得越來越難以維護(hù),質(zhì)量也越來越差。而單元測試就是解決這種問題的很好方法(不敢說最好的)。由于代碼的歷史功能都有相應(yīng)的單元測試保證,修改了某些代碼以后,通過運(yùn)行相關(guān)的單元測試就可以驗(yàn)證出新調(diào)整的功能是否有影響到之前的功能。當(dāng)然要實(shí)現(xiàn)到這種程度需要很大的付出,不但要能夠達(dá)到比較高的測試覆蓋率,而且單元測試代碼的編寫質(zhì)量也要有保證。

4.她能為你排憂解難,永遠(yuǎn)做你的依靠。讓你的代碼維護(hù)更容易。
由于給代碼寫很多單元測試,相當(dāng)于給代碼加上了規(guī)格說明書,開發(fā)人員通過讀單元測試代碼也能夠幫助開發(fā)人員理解現(xiàn)有代碼。比如開源項(xiàng)目(如AFNetworking, FMDB,喵神的VVDoucment等)都有相當(dāng)量的單元測試代碼,通過讀這些測試代碼會(huì)有助于理解生產(chǎn)源代碼。

5.她甘心做你堅(jiān)強(qiáng)的后盾,在你賣命打拼時(shí)無后顧之憂。她有助于改進(jìn)代碼質(zhì)量和設(shè)計(jì)。
除了那些大拿們編寫的代碼,我相信很多易于維護(hù)、設(shè)計(jì)良好的代碼都是通過不斷的重構(gòu)才得到的。雖然說單元測試本身不能直接改進(jìn)生產(chǎn)代碼的質(zhì)量,但它為生產(chǎn)代碼提供了“安全網(wǎng)”,讓開發(fā)人員可以勇敢地改進(jìn)代碼,從而讓代碼的clean和beautiful不再是夢想。

說了那么多,其實(shí)就是想表明基于測試驅(qū)動(dòng)的開發(fā),對你來說就達(dá)到了事半功倍的目的。

具體例子可以看看官網(wǎng)的Demo或者Google下了。https://developer.apple.com/library/content/samplecode/UnitTests/Introduction/Intro.html

Test 斷言

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í)使用,實(shí)際測試發(fā)現(xiàn)NSString也可以);

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í)通過測試,反之不通過。

特別注意下XCTAssertEqualObjects和XCTAssertEqual。
XCTAssertEqualObjects(a1, a2, format...)的判斷條件是[a1 isEqual:a2]是否返回一個(gè)YES。XCTAssertEqual(a1, a2, format...)的判斷條件是a1 == a2是否返回一個(gè)YES。對于后者,如果a1和a2都是基本數(shù)據(jù)類型變量,那么只有a1 == a2才會(huì)返回YES。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容