如何寫好單元測(cè)試(php程序猿)

phpunit單元測(cè)試(demo):https://github.com/qq1060656096/phpunit-test

百度經(jīng)驗(yàn)地址:http://jingyan.baidu.com/article/597a0643239f36312b524386.html

很多沒(méi)寫個(gè)單元測(cè)試的朋友,總覺(jué)得單元測(cè)試很難,還增加了工作了,或者把單元測(cè)試環(huán)境搭好了,也寫了很多單元測(cè)試,越寫越累,感覺(jué)代碼質(zhì)量沒(méi)提高,工作量反而提高很多。我們一起來(lái)學(xué)習(xí)下如何寫好單元測(cè)試。

我們分以下7個(gè)小點(diǎn)來(lái)講解:

1. ?為什么要些單元測(cè)試?

2. 單元測(cè)試與集成測(cè)試的區(qū)別?

3. 先些代碼還是先寫單元測(cè)試?

4. 誰(shuí)來(lái)編寫單元測(cè)試 ?

5. 如何避免無(wú)用的測(cè)試 ?

6. 測(cè)試代碼覆蓋率?

7. 單元測(cè)試中的"mock仿件"或者我們說(shuō)的打樁?


1. 為什么要些單元測(cè)試?

目的:

1. 提高軟件質(zhì)量

2. 減少bug

3. 減少重復(fù)的工作

4. 安全的重構(gòu)已有的代碼

5. 讓開(kāi)發(fā)者對(duì)程序穩(wěn)定性更有信心

重要性:

1. 運(yùn)行單元測(cè)試是為了保證代碼的行為和我們期望的結(jié)果一致。

2. 寫單元測(cè)試會(huì)增加代碼工作量,同時(shí)也節(jié)約了bug修復(fù)時(shí)間。

3. 如果沒(méi)有寫單元測(cè)試,沒(méi)有發(fā)現(xiàn)bug的情況下,程序在測(cè)試人員測(cè)試的時(shí)候才發(fā)現(xiàn)問(wèn)題或者在線上環(huán)境(正式環(huán)境)用戶使用才發(fā)現(xiàn)問(wèn)題,在去修復(fù)bug。開(kāi)發(fā)會(huì)花大量的精力去修復(fù)bug和走部署流程,測(cè)試也會(huì)花大量的時(shí)間去做了重復(fù)的測(cè)試。很不劃算。

4. 在線上某些場(chǎng)景下bug導(dǎo)致大量的數(shù)據(jù)丟失,需要花很大精力去修復(fù)數(shù)據(jù),或者根本沒(méi)辦修復(fù)數(shù)據(jù)導(dǎo)致嚴(yán)重的后果。


2. 單元測(cè)試與集成測(cè)試區(qū)別?

測(cè)試粒度不同:單元測(cè)試是程序最小的單元,而集成測(cè)試是一個(gè)功能,一組功能或者整個(gè)系統(tǒng)上

單元測(cè)試:程序的最小單元。

集成測(cè)試:也叫組裝測(cè)試或聯(lián)合測(cè)試,是在單元測(cè)試的基礎(chǔ)上,把所有模塊按系統(tǒng)設(shè)計(jì)要求組裝成功能或者系統(tǒng),實(shí)際中程序單元,測(cè)試通過(guò)了,不能保證程序組裝也能正常的工作,程序某些在局部反應(yīng)不出問(wèn)題,很有可能在全局或者特殊場(chǎng)景下暴露出問(wèn)題。

單元測(cè)試和集成測(cè)試很容易混為一談:因?yàn)閱卧獪y(cè)試和集成測(cè)試可以試用相同的工具和框架編寫。

3. 先寫代碼還是先寫單元測(cè)試?

編碼前,要先寫測(cè)試,很多沒(méi)有寫過(guò)單元測(cè)試的朋友會(huì)想,代碼都沒(méi)有,連測(cè)試的對(duì)象都沒(méi)有,我怎么寫單元測(cè)試?

1. 我們可以通過(guò)先話流程圖,寫偽代碼或者建模來(lái)解決這個(gè)問(wèn)題,這樣讓我們站在用戶的角色去開(kāi)發(fā),盡早的發(fā)現(xiàn)問(wèn)題

2. 避免我們開(kāi)發(fā)完了,某個(gè)功能模塊遺漏了的情況。

3. 這樣開(kāi)發(fā)出來(lái)的程序擴(kuò)展性、維護(hù)性很容易理解。


4. 誰(shuí)來(lái)編寫單元測(cè)試?

單元測(cè)試一般由開(kāi)發(fā)員自己些,但是我們自己對(duì)自己的代碼編寫單元測(cè)試的情況下,習(xí)慣性的往理想情況下編寫,開(kāi)發(fā)員最好不要針對(duì)自己的代碼編寫單元測(cè)試。應(yīng)該有其他開(kāi)發(fā)編寫,這樣減少了bug也提高了開(kāi)發(fā)的水平。

5. 如何避免無(wú)用的測(cè)試?

1. 只寫必要的測(cè)試

編寫自己覺(jué)得不靠譜的代碼,例如業(yè)務(wù)很復(fù)雜自己沒(méi)有吃透,以前沒(méi)有寫過(guò),感覺(jué)會(huì)產(chǎn)生無(wú)法預(yù)料的結(jié)果。

2. 只寫關(guān)鍵的測(cè)試

有時(shí)候必要的測(cè)試我們些不出來(lái),也沒(méi)有人知道,我們只能勉強(qiáng)跳過(guò)。但是關(guān)鍵性的測(cè)試不能跳過(guò),關(guān)鍵性測(cè)試就是:你寫的代碼的核心洛基。如果你不知道怎么處理,你知道要保證最終要的那條路線是可以走通的,將來(lái)重構(gòu)的時(shí)候,這條路線能確保你不會(huì)茫然。

3. 無(wú)用的測(cè)試

3.1 不要去測(cè)試開(kāi)發(fā)語(yǔ)言的標(biāo)準(zhǔn)庫(kù)和核心庫(kù),因?yàn)檫@些代碼都是久經(jīng)考驗(yàn)過(guò)得。雖然這些會(huì)出現(xiàn)小概率的錯(cuò)誤。(如果你確定是開(kāi)發(fā)語(yǔ)言的標(biāo)準(zhǔn)庫(kù)或者核心庫(kù)的問(wèn)題,你應(yīng)該測(cè)試標(biāo)準(zhǔn)庫(kù)和核心庫(kù),因?yàn)樗鼈兌紟в型暾臏y(cè)試用例)

3.2 不要去測(cè)試基礎(chǔ)框架和工具方法和外部依賴的有效性,當(dāng)你遇到這種問(wèn)題,你應(yīng)該打樁"mock"。

3.3 你只見(jiàn)過(guò)它測(cè)試通過(guò),沒(méi)有見(jiàn)過(guò)它測(cè)試失敗,可能這種測(cè)試從頭到尾都沒(méi)測(cè)試任何代碼,我們應(yīng)該手動(dòng)破壞代碼,以確保幀的覆蓋到了目標(biāo)代碼。

6. 測(cè)試代碼覆蓋率?

我們應(yīng)該忽略代碼覆蓋率:就算覆蓋率達(dá)到100%,和"靠譜"的代碼肯能有天壤之別,問(wèn)題就在于有些公司把代碼覆蓋率作為考核的標(biāo)準(zhǔn),這就讓開(kāi)發(fā)很容易就演變成"追求100%代碼覆蓋率",然后無(wú)所不用,連開(kāi)發(fā)都不懂,那就更悲劇了,一群人對(duì)著水分極大的代碼,然后對(duì)著"100%代碼覆蓋率"樂(lè)得合不弄嘴想想都難受想哭。

測(cè)試中的仿件"mock"或者我們說(shuō)的打樁?

有時(shí)候?qū)Ρ粶y(cè)試的系統(tǒng)進(jìn)行測(cè)試很困難,因?yàn)樗蕾嚐o(wú)法在測(cè)試環(huán)境中使用的對(duì)象、組件、API或者它們不可用。在這種情況下,我們確保測(cè)試系統(tǒng)的內(nèi)部行為有更多的控制性和可見(jiàn)性,我們可以使用仿件"mock"或者打樁。

7. 什么情況下使用"仿件mock、樁件stubs" ?

1. 外部依賴不存在。

2. 外部依賴不會(huì)返回測(cè)試需要的結(jié)果,或者它有不良的副作用。

3. 如果外部依賴更變,會(huì)導(dǎo)致我們的測(cè)試失敗。

我們來(lái)看一個(gè)打樁示例:

1. 我們?cè)诰帉憜卧獪y(cè)試購(gòu)物車"Cart"類,依賴產(chǎn)品類"Product"和用戶類"User"。

2. 依賴產(chǎn)品類"Product"和用戶類"User"已經(jīng)測(cè)試過(guò)了。

3. 依賴的產(chǎn)品類"Product"和用戶類"User"是由他人開(kāi)發(fā)的。

示例問(wèn)題:

1. 產(chǎn)品類"Product"和用戶類"User"一旦出現(xiàn)問(wèn)題,不會(huì)讓我們誤以為購(gòu)物車類"Cart"出了問(wèn)題。

2. 不用為了創(chuàng)造很多前置條件,才能做出斷言。(如果這樣你應(yīng)該把它放到集成測(cè)試)。

3. 在測(cè)試購(gòu)物車時(shí),我們應(yīng)該避免使用"new Cart($userId, $productId, $quantity)"這種方式,這樣會(huì)出現(xiàn)程序中很多地方都去做了重復(fù)的查詢,并且影響程序的執(zhí)行效率,更不利于打樁,我們應(yīng)該使用這種方式"new Cart(User $user, Product $product, $quantity)"

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,182評(píng)論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,489評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事?!?“怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,290評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,776評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,510評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,866評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,860評(píng)論 3 447
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,036評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,585評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,331評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,536評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,058評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,754評(píng)論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,154評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,469評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,273評(píng)論 3 399
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,505評(píng)論 2 379

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,734評(píng)論 25 708
  • 一、百變怪 Mockito Mockito可謂是Java世界的百變怪,使用它,可以輕易的復(fù)制出各種類型的對(duì)象,并與...
    羅力閱讀 3,956評(píng)論 3 18
  • 文章來(lái)自:http://blog.csdn.net/mj813/article/details/52451355 ...
    好大一只鵬閱讀 9,213評(píng)論 2 126
  • 1.測(cè)試與軟件模型 軟件開(kāi)發(fā)生命周期模型指的是軟件開(kāi)發(fā)全過(guò)程、活動(dòng)和任務(wù)的結(jié)構(gòu)性框架。軟件項(xiàng)目的開(kāi)發(fā)包括:需求、設(shè)...
    Mr希靈閱讀 21,980評(píng)論 7 278
  • 1 和W是高中同學(xué),畢業(yè)之后也沒(méi)見(jiàn)過(guò)面,僅從朋友圈了解。后來(lái)有一次約著見(jiàn)面吃飯。帶著欣喜的心情去見(jiàn)她,老遠(yuǎn)就已經(jīng)認(rèn)...
    巷西閱讀 530評(píng)論 4 2