最近部分采用了TDD的方法來開發(fā)一個(gè)模塊,小有收獲特此總結(jié)一下:
1. TDD的基本原則
TDD的最核心思想就是先明確需求,且用代碼的方式量化,明確需求標(biāo)準(zhǔn),然后進(jìn)行編碼實(shí)現(xiàn)以達(dá)成由代碼測(cè)試來衡量的標(biāo)準(zhǔn)。
那么它要求,先把需要標(biāo)準(zhǔn)寫出來,每次只寫一個(gè)。編碼實(shí)現(xiàn)通過達(dá)到,并剛好滿足這個(gè)標(biāo)準(zhǔn)。這樣一點(diǎn)一點(diǎn)的迭代。
這樣有三個(gè)好處:一個(gè)是先明確標(biāo)準(zhǔn),不至于我們迷失主題,偏離方向。有標(biāo)準(zhǔn)在檢測(cè),保證代碼是正確的。僅滿足當(dāng)前測(cè)試,不至于過早優(yōu)化和過度設(shè)計(jì)。
2. TDD的難點(diǎn)
難點(diǎn)在于如何設(shè)計(jì)這個(gè)測(cè)試標(biāo)準(zhǔn),
1)讓它足夠小,是一個(gè)需求單元;
2)成為標(biāo)準(zhǔn),也就是如何檢測(cè)正確性;
3)就是如何在最大程度模擬真實(shí)運(yùn)行的場(chǎng)景,而不是為了測(cè)試而寫出許多額外的工具,也就是說測(cè)試應(yīng)該跟真實(shí)的項(xiàng)目代碼一樣,不應(yīng)該有多余的東西。
這關(guān)鍵在于要分析挖掘需求,并細(xì)化需求。如果都像書中的例子那樣測(cè)試一些API那倒是很好寫,因?yàn)闇y(cè)試代碼跟真實(shí)的App代碼用一樣的方式來調(diào)用API,而且API的功能也會(huì)有明確的描述。但現(xiàn)實(shí)情況并非如此,比如很多框架就很難測(cè)試,很多對(duì)象和創(chuàng)建和控制都是由框架來做,你無法像控制。這就導(dǎo)致了很難寫測(cè)試用例。
還有就是多線程,由于線程帶來的不確定性,有很多偽失敗,這可以參考書,書中有方法。
3. Android中的TDD
老實(shí)說,在Android完全用TDD的方法來開發(fā)是不可能的。原因如下:
1. Android中的應(yīng)用程序主要結(jié)構(gòu)是四大組件:Service,Activity和Provider和Receiver這四東西的創(chuàng)建和銷毀都是由框架來控制。所以你不可能像書中例子那樣去測(cè)試它們,因?yàn)橛行┫拗谱屇銦o法用代碼來測(cè)試。
2. 有些東西是系統(tǒng)框架的回調(diào)或者很基本東西根本不用寫TestCase。比如View的Click/LongClick/Touch事件的處理之類的,或者Activity的生命周期回調(diào),或者OptionsMenu/ContextMenu之類的。
3. SDK中的用于測(cè)試的API功能太弱
這就導(dǎo)致了,為了測(cè)試一個(gè)小功能需要做很多工作和寫很多代碼,遠(yuǎn)大于直接實(shí)現(xiàn)。比如測(cè)試一個(gè)彈出的Dialog,如果直接實(shí)現(xiàn)很容易;但如果用代碼來測(cè)試就要多3,4倍的工作量,遠(yuǎn)大于直接實(shí)現(xiàn)。
4. 那么在Android中應(yīng)該如何運(yùn)用好TDD呢?以下是一些建議:
1. 使用Robotium
這是強(qiáng)大的工具,它比SDK中的東西可是方便的很多比如searchText,clickMenu之類的接口非常的方便和實(shí)用。
2. 自動(dòng)測(cè)試+手動(dòng)測(cè)試
同樣要遵循原則,但是對(duì)于測(cè)試用例,沒有必要完全用代碼來寫,可以部分手動(dòng)測(cè)試:一般的原則來講如果自動(dòng)測(cè)試比較方便的實(shí)現(xiàn)就寫TestCase,如果手動(dòng)測(cè)試很方便就手動(dòng)測(cè)試,這沒有死規(guī)則要看具體的情況。
比如,View的事件,Activity的事件,Activity的Menu,Dialog之類的與交互相關(guān)的東西,以及跨應(yīng)用交互的用例最好手動(dòng)來測(cè)試,因?yàn)檫@些東西用代碼來測(cè)試更麻煩。
但對(duì)于一些涉及數(shù)值,計(jì)算,量化等就用代碼來做。比如下載一個(gè)文件,設(shè)定好路徑后就可以直接用File對(duì)象來檢測(cè)文件是否下載成功。
3. Provider必須要測(cè)試
Provider提供的是API,它非常好測(cè)試也容易寫,又是一個(gè)項(xiàng)目的基本設(shè)施,所以必須要好好測(cè)試,否則如果在Activity上某條數(shù)據(jù)有問題,你必須要確定是顯示上出了問題還是Provider里出了問題。通常CRUD必須測(cè)試,還有就是where語句,以及逆向測(cè)試,必須要檢測(cè)Uri的合法性等,還有就是要檢測(cè)對(duì)特殊字符的處理,比如'和"。
4. 除Service和Activity以外的東西,特別是自己實(shí)現(xiàn)的類似API的類,如果里面涉及一些業(yè)務(wù)邏輯也要進(jìn)行測(cè)試。這就跟書中的例子差不多了,測(cè)試的難易成就也取決于業(yè)務(wù)的分解,設(shè)計(jì)和耦合度了。
5. 用反射來測(cè)試類的內(nèi)部
對(duì)于Service和Activity雖然可以在TestCase中拿到它的實(shí)例,但是Service和Activity是一個(gè)組件單元在實(shí)際中并不會(huì)Public太多的接口,它們是處于最頂端的調(diào)用其他接口,而自己不會(huì),也不應(yīng)該公開接口給別人用,原因就是它們的創(chuàng)建和生命周期的管理都是由系統(tǒng)控制的,別處不應(yīng)該有太多對(duì)它們的引用。
那么當(dāng)要測(cè)試Service和Activity內(nèi)部時(shí)怎么辦呢?比如要測(cè)試某個(gè)Service內(nèi)部的一個(gè)int[] mPlaylistQueue。我們總不能為了寫Case而在Service中加接口吧!這時(shí)就要用反射機(jī)制來取出這個(gè)成員的實(shí)例,然后檢查它的數(shù)據(jù)。
6. 有些東西必須手動(dòng)測(cè)試,自動(dòng)化無法完成
TestCase是有特殊的Context和MockObject的,它是對(duì)真實(shí)Android運(yùn)行的一個(gè)最大化的模擬,它并不跟應(yīng)用真正運(yùn)行時(shí)的情況完全一樣!而且由于Permission的原因,某些事情Instrumentation是無法做的,比如Alarm,日期等Instrumentation是無權(quán)限更改的。這些必須要靠手動(dòng)測(cè)試。
還有就是Service和Activity的初始化和銷毀,特別是銷毀,沒辦法測(cè)試,也就是說對(duì)于onDestroy()里面的東西,還真的不好去測(cè)試。第一,你不知道它何時(shí)被回調(diào)到;第二,執(zhí)行到它時(shí)對(duì)象快被銷毀了,你持有的引用不一定有效了;第三,成員對(duì)象是否都有效也無法得知。對(duì)于onDestroy只能通過調(diào)試手段手動(dòng)的去測(cè)試。
總之,在我看來,TDD的核心思想是測(cè)試先來,實(shí)現(xiàn)后來。但如何測(cè)試并沒有列規(guī)定非要用代碼,所以根據(jù)實(shí)際情況,選擇最佳的測(cè)試手段。
Android開發(fā)筆記之:對(duì)實(shí)踐TDD的一些建議說明
2021-01-16 14:11Android開發(fā)網(wǎng) Android
本篇文章是對(duì)Android中實(shí)踐TDD的一些建議進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
延伸 · 閱讀
- 2022-03-11Android String類型轉(zhuǎn)換為float、double和int的工具類方
- 2022-03-11Android 8.1 Launcher3實(shí)現(xiàn)動(dòng)態(tài)指針時(shí)鐘功能
- 2022-03-11Android控件Spinner實(shí)現(xiàn)下拉列表及監(jiān)聽功能
- 2022-03-11詳解Android獲取所有依賴庫的幾種方式
- 2022-03-11Android 仿高德地圖可拉伸的BottomSheet的示例代碼
- 2022-03-11Android 優(yōu)化之卡頓優(yōu)化的實(shí)現(xiàn)
- Android
淺談Android系統(tǒng)的基本體系結(jié)構(gòu)與內(nèi)存管理優(yōu)化
這篇文章主要介紹了Android系統(tǒng)的基本體系結(jié)構(gòu)與內(nèi)存管理優(yōu)化,非常簡(jiǎn)潔明了地總結(jié)了系統(tǒng)服務(wù)及垃圾回收等安卓的一些主要特性,需要的朋友可以參考下...
- Android
Android控件系列之CheckBox使用介紹
CheckBox和Button一樣,也是一種古老的控件,它的優(yōu)點(diǎn)在于,不用用戶去填寫具體的信息,只需輕輕點(diǎn)擊,缺點(diǎn)在于只有“是”和“否”兩種情況,但我們往...
- Android
Android中掃描多媒體文件操作詳解
這篇文章主要介紹了Android中掃描多媒體文件操作詳解,本文講解了Android中的多媒體文件掃描機(jī)制、如何掃描一個(gè)剛創(chuàng)建的文件、如何掃描多個(gè)文件,需要的朋...
- Android
Android開發(fā)筆記之:對(duì)實(shí)踐TDD的一些建議說明
本篇文章是對(duì)Android中實(shí)踐TDD的一些建議進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下...
- Android
解析Android應(yīng)用程序運(yùn)行機(jī)制
這篇文章主要介紹了Android應(yīng)用程序運(yùn)行機(jī)制,有需要的朋友可以參考一下...
- Android
Android編程中EditText限制文字輸入的方法
這篇文章主要介紹了Android編程中EditText限制文字輸入的方法,涉及Android針對(duì)EditText的監(jiān)聽技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下...
- Android
使用RadioButton+Fragment實(shí)現(xiàn)底部導(dǎo)航欄效果
這篇文章主要為大家詳細(xì)介紹了使用RadioButton+Fragment實(shí)現(xiàn)底部導(dǎo)航欄效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下...
- Android
Android Animation實(shí)戰(zhàn)之屏幕底部彈出PopupWindow
這篇文章主要為大家介紹了Android Animation動(dòng)畫實(shí)戰(zhàn)項(xiàng)目,屏幕底部彈出PopupWindow,如何實(shí)現(xiàn)?文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的...