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

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

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

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

我們分以下7個小點來講解:

1. ?為什么要些單元測試?

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

3. 先些代碼還是先寫單元測試?

4. 誰來編寫單元測試 ?

5. 如何避免無用的測試 ?

6. 測試代碼覆蓋率?

7. 單元測試中的"mock仿件"或者我們說的打樁?


1. 為什么要些單元測試?

目的:

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

2. 減少bug

3. 減少重復的工作

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

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

重要性:

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

2. 寫單元測試會增加代碼工作量,同時也節(jié)約了bug修復時間。

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

4. 在線上某些場景下bug導致大量的數(shù)據(jù)丟失,需要花很大精力去修復數(shù)據(jù),或者根本沒辦修復數(shù)據(jù)導致嚴重的后果。


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

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

單元測試:程序的最小單元。

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

單元測試和集成測試很容易混為一談:因為單元測試和集成測試可以試用相同的工具和框架編寫。

3. 先寫代碼還是先寫單元測試?

編碼前,要先寫測試,很多沒有寫過單元測試的朋友會想,代碼都沒有,連測試的對象都沒有,我怎么寫單元測試?

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

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

3. 這樣開發(fā)出來的程序擴展性、維護性很容易理解。


4. 誰來編寫單元測試?

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

5. 如何避免無用的測試?

1. 只寫必要的測試

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

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

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

3. 無用的測試

3.1 不要去測試開發(fā)語言的標準庫和核心庫,因為這些代碼都是久經(jīng)考驗過得。雖然這些會出現(xiàn)小概率的錯誤。(如果你確定是開發(fā)語言的標準庫或者核心庫的問題,你應該測試標準庫和核心庫,因為它們都帶有完整的測試用例)

3.2 不要去測試基礎框架和工具方法和外部依賴的有效性,當你遇到這種問題,你應該打樁"mock"。

3.3 你只見過它測試通過,沒有見過它測試失敗,可能這種測試從頭到尾都沒測試任何代碼,我們應該手動破壞代碼,以確保幀的覆蓋到了目標代碼。

6. 測試代碼覆蓋率?

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

測試中的仿件"mock"或者我們說的打樁?

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

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

1. 外部依賴不存在。

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

3. 如果外部依賴更變,會導致我們的測試失敗。

我們來看一個打樁示例:

1. 我們在編寫單元測試購物車"Cart"類,依賴產(chǎn)品類"Product"和用戶類"User"。

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

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

示例問題:

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

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

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

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

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

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

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