我是3y,一年CRUD
經驗用十年的markdown
程式設計師???常年被譽為職業八股文選手
最近在看單元測試的東西,想跟大家聊聊我的感受。單元測試這塊說實在的,我並不太熟悉,我幾乎不寫單元測試,也不太愛寫單元測試。
當我推廣訊息推送平臺austin的時候,有過批評我整個專案沒有單元測試,也有過讓我補上單元測試的。
01、單元測試(UNIT TEST)
我有個前同事進了外企,他說進了外企以後學習了很多新名詞,剛進去時都不知道他們講的是什麼...
他問我:UT你知道是什麼意思嗎?
我說:不知道啊。
他說:UT是Unit Test,單元測試
我說:你們現在都要寫單元測試嗎?
他說:是啊
後來,我在群裡閒聊的時候,發現有個企鵝上班的大哥也不知道UT是什麼意思,那我就放心了。
02、測試型別有什麼
測試型別對於我們開發人員來說,或許可以歸納分為三類:
1、單元測試:對某個類中的程式碼進行測試,檢視是否正常
2、整合測試:跨模組測試檢視程式碼是否正常
3、端到端測試:以使用者的角度把系統作為一個整體看功能是否正常
所以,在我們程式設計師裡談單元測試的時候,可能會是純單元測試,也可能是整合測試,畢竟這塊大機率都應該是我們乾的。
03、為什麼要單元測試
對於我這種不怎麼寫單元測試的,也不愛寫單元測試的,在我的嘴裡自然就編不出要寫單元測試的理由了,倒是不寫單元測試的理由是一堆堆的。
說到單元測試,就不得不提起另一個詞,TDD(Test-Driven Development)測試驅動開發:在開發功能程式碼之前,先編寫單元測試用例程式碼,測試程式碼確定需要編寫什麼產品程式碼
測試驅動開發雖然飽受爭議,不過有這種方法論的推出並有不少的同行在踐行,起碼能夠說明測試的重要性。
1、當我們想測試部分程式碼邏輯是否正常的時候,我們可能會直接psvm
來構造資料進而除錯。那如果有一種東西能把我們psvm
統一放到某個地方呢?
2、當我們在一個系統裡邊修改了很多程式碼時,又不確定改動是否影響在核心邏輯時。那如果有一種東西能在編譯的時候,順便自動跑一遍邏輯做迴歸呢?無論是重構還是正式提測前,都提高了自己寫程式碼的信心。
3、當我們很容易一不小心時就把程式碼寫成一坨屎,那如果有一種東西能讓我們在編碼的時候就注重自己的程式碼設計呢?
4、當我們這個季度什麼都沒幹,但是系統沒發生過故障,那如果有一種東西能讓我們在KPI上添上濃墨的一筆呢?
5、....歡迎補充
沒錯,這東西就是單元測試。
04、單元測試怎麼寫?
很長一段時間裡,怎麼寫單元測試我的知識就停留在Junit上。後來,跟我那個進外企的小夥伴以及群裡的滴滴哥交流了以後,發現他們都會用Mockito這個框架去寫單元測試
在這個過程中, 我看了些關於Mockito單元測試的文章,但總會有專業術語給我勸退,到這裡我就很明白,我要邊寫邊看了。
1、SpringBoot環境下使用Mockito只需要引入spring-boot-starter-test
就好了,預設內建了Mockito相關的依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
2、我們單元測試是寫在對應的test目錄下的,想想都知道會有外掛可以幫我們透過主類成為出對應的測試類,是不需要我們手動去建包和建測試類的。
於是,我找到了squaretest外掛
3、看幾篇Mockito相關的教程,瞭解其API和概念,推薦下這個教程: https://www.letianbiji.com/ja...
4、親自動手寫一個單元測試,瞭解其編寫過程和感受體驗
有的人可能看到這裡就要問了:為什麼要用Mockito這種測試框架而不是純用Junit? 在我的看來,答案就是:我們在測試時物件可能是Spring下的,我們不能直接new,又或是new出來的物件成本很大(還得解決依賴等問題)
這時候,我們就需要Mock物件出來模擬我們建立了這個物件,而在學習Mockito測試框架在這個過程中,其實就是對Mock/Stub/Spy概念的理解以及他們的使用。
Mock和Spy都是模擬建立出一個物件,區別在於Spy模擬建立出的物件是會真實呼叫方法的,而Mock模擬建立出的物件是不會真實呼叫方法的
那Mock模擬建立出來的物件不會呼叫真實方法,但我們又想驗證其流程怎麼辦?
比如,我在寫service
層的單元測試,我認為dao
層的程式碼是正常的,但是service
是需要dao
的物件訪問資料庫的,這時候我Mock出dao
的模擬物件,去呼叫方法。
所以我會假定呼叫dao
層的某方法時它的返回值是什麼,這個過程就是Stub
05、整合測試怎麼寫
在剛剛,我們使用Mockito的時候,是沒有依賴Spring環境的,物件都是Mock出來的,速度槓槓的,非常快。但我們很多時候可能是需要依賴Spring環境跨模組去除錯功能是否正常。
這時候,我們就要使用 @SpringTest來修飾測試類指明我這個是需要Spring環境的。既然有了Spring環境,那 @Autowire之類的註解都是可以用的。
在web模組下啟動的話,你會發現它就真的啟動了應用相關的環境,然後專門跑了這個測試方法。
05、為什麼我不愛寫單元測試
我是寫完了業務程式碼,然後再回過頭來寫單元測試。單元測試是我自己寫的,我Mock出來模擬物件再Stub,整個過程中我都是認為我寫的程式碼是正確的。
寫完了以後,看到綠色的條框我並不意外,畢竟我是對著我的業務程式碼寫的單元測試。而整合測試都把Spring環境相關的依賴都整進去了,我直接在本地啟動服務也能自己調呀。
(我相信看到這篇文章絕大多數人都不是TDD模式開發,應該都是對著自己寫好的業務程式碼寫單元測試)
寫單元測試的程式碼也是程式碼,也是要花時間的呀
我也去問了騰訊/滴滴/阿里/位元組的朋友,發現他們也不愛寫單測,很多時候寫單測就是為了透過編譯,為了業務的覆蓋率,能繞開就繞開了。
為什麼沒有問京東/拼多多/美團/網易等等的?別問,問就是還沒太熟。
看到這篇文章的同行肯定是有在團隊推行寫單元測試的,不妨在評論區寫下理由拯救一下我們這些迷途不愛寫單元測試的羔羊。
如果想學Java專案的,我還是強烈推薦我的開源專案訊息推送平臺Austin,可以用作畢業設計,可以用作校招,可以看看生產環境是怎麼推送訊息的。
austin訊息推送平臺專案原始碼Gitee連結:gitee.com/austin
austin訊息推送平臺專案原始碼GitHub連結:github.com/austin