對單元測試的一點感悟

2022-03-12 06:18:04 字數 3011 閱讀 9399

想 當年畢業設計就是測試驅動開發,所以從剛入行開始就對單元測試、測試驅動開發有比較深入的認識,剛開始一直作為敏捷開發的忠實粉絲。但是幾年工作下來,我 開始對單元測試持矛盾的態度:單元測試當然是一種很好的創舉,但是具體使用當中,它卻經常會產生***。這當然不是因為單元測試這一思想有問題,而是實踐 這一思想的人的問題。

當前很多公司使用單元測試的怪現象:

很多公司為了說出去

好看——我們的開發遵循敏捷開發,擁有近100%的單元測試覆蓋率,所以**質量有非常可靠的保障。但是實際上,單元測試都是軟體已經開發完成之後加上去

的,而且經常還是由專門分配的幾個人去寫單元測試的,而這幾個人根本不熟悉需求,甚至根本沒有參與開發過程,或者參與得很少,而分配給他們寫單元測試**

的時間當然也很緊張,因為這也是需要成本的。所以,最終導致的結果就是——為了達到覆蓋率目標,為每個方法(不管有無必要)加上單元測試,簡單看一下這個

方法,然後從對這個方法的膚淺理解出發,即開始動手,寫乙個或很少的幾個測試用例,這樣單元測試覆蓋率100%的要求就達到了,可是這樣的單元測試有用

嗎?答案不言自明。

這種怪現象一般可能具備哪些特徵呢?

1、整個開發過程完全之後寫單元測試——這是單元測試的時機問題

2、由非開發過程的參與者寫單元測試——這是單元測試的執行者的角色問題

3、由不了解需求的人員寫單元測試——這也是單元測試的執行者的角色問題

那麼,這種行為會帶來哪些***呢?

1、這浪費了時間和人力成本

2、這會帶來負面的情緒影響

這些人是帶著牴觸的厭煩的情緒投入工作的,因為明知這樣的工作是無用功,僅僅是面子工程,卻不得已而為之,自然沒有興趣沒有熱情,而這一情緒會橫向和縱向地散發,從而給團隊帶來負面的影響。

3、這些單元測試**毫無用處,甚至產生負作用

對於後來者來說,這種單元測試**沒有任何作用,因為寫作者本就是在不了解需求的基礎上倉促寫就的,那麼自然對後來者理解需求沒有任何益處;而且如果後來者相信的這份單元測試**,沒有充分地調查具體的實現**,還會因此產生誤解。

單元測試到底要怎麼寫?何時寫?

這是乙個很值得**的問題,但是有十足的必要。

在酷殼上看到「單元測試要做多細」這篇文章,文章是從stackoverflow上的乙個問題開始引入的。

這個問題是:

tdd需要花時間寫測試,而我們一般多少會寫一些**,而第乙個測試是測試我的建構函式有沒有把這個類的變數都設定對了,這會不會太過分了?那麼,我們寫單元測試的這個單元的粒度到底是什麼樣的?並且,是不是我們的測試測試得多了點?

問題的最佳答案是:

老闆為我的**付報酬,而不是測試,所以,我對此的價值觀是——測試越少越好,少到你對你的**質量達到了某種自信(我覺得這種的自信標準應該要高於業內的

標準,當然,這種自信也可能是種自大)。如果我的編碼生涯中不會犯這種典型的錯誤(如:在建構函式中設了個錯誤的值),那我就不會測試它。我傾向於去對那

些有意義的錯誤做測試,所以,我對一些比較複雜的條件邏輯會異常地小心。當在乙個團隊中,我會非常小心的測試那些會讓團隊容易出錯的**。

看了這個最佳答案,給人感覺對單元測試持一定的否定態度和不感冒態度。但是知道這一最佳答案的回答者是誰嗎?是kent

beck。對,正是那位極限程式設計、測試驅動開發和單元測試以及junit的創造者kent beck。kent

beck的答案,正好回答了單元測試該怎麼寫、要寫到什麼程度、何時應該寫這幾個問題。

我的一些觀點:

對於如何進行單元測試,有這麼幾個觀點:

一、單元測試的時機很重要

無非兩種:

一是在具體實現**之前,這就是所謂的測試驅動開發;

二是與具體實現**同步進行,正是大部分人採用的方式。

那種事後單元測試,基本是沒用的。當然有一種例外:要對沒有單元測試的既有**進行維護和改造,這時候需要為既有**追加單元測試,但是這也得建立在充分調查理解需求的基礎上才能進行。

二、單元測試的執行者的角色

單元測試應當由具體實現**的開發者進行,也就是說每個開發人員都應當同時對自己負責具體實現**和單元測試**負責。

這裡也存在同第一條中的例外的情況。

三、單元測試應當突出重點

應當對那些重點部分重點關照,主要有:

1、邏輯複雜的

2、容易出錯的

3、不易理解的,即使是自己過段時間也會遺忘的,看不懂自己的**,單元測試**有助於理解**的功能和需求

4、後期需求變更可能性相對比較大的,這樣後期需求更變修改**之後就不用太擔心寫的**對不對以及是否破壞既存**邏輯了

四、單元測試也應注重質量,不要寫無用的測試**

寫沒有實際用處的單元測試不如不寫,正如注釋,寫沒有意義的注釋也不如不寫,既降低**可讀性又容易誤人子弟。

五、敏捷開發的宗旨是「以人為本」,是解放,而不是壓迫

單元測試雖說從長期來看,可以提高**質量、減少維護成本、降低重構難度,擁有眾多好處。但是從短期來看,肯定是會加大工作量的,也就是說需要投入更多的人

力成本,如果只想得到好處,卻不願投入相應的成本,還是不要搞單元測試了——那只會導致開發人員更多的加班,不會產生好的效果。因為整個敏捷開發的宗旨,

是「以人為本」,而不是從開發人員身上榨出更多的油水。單元測試是為了解放開發人員,而不是壓迫,是為了從長遠的角度減輕開發人員的工作量!

最後要說的是:

那種為了單元測試而單元測試的愚蠢行為應當立即停止。

那種只是想把單元測試作為一項面子工程的行為更應當停止(官場的種種壞習慣不應該在思想純潔的程式設計師當中流行)。

那些對單元測試沒有深入理解,只是希望今後能冠以「單元測試覆蓋率100%」榮譽頭銜的團隊,應該立即停止這種想法。

單元測試不應當過於重視覆蓋率,而應該在需要的時候寫單元測試。何時寫,怎麼寫,都需要建立在開發者已經對單元測試有深刻理解的基礎上。

單元測試也是一把雙刃劍,要用得好它才能發光發熱,產生強大的正能量,請不要把它當作「龍泉寶劍」掛在自家的玄關辟邪。

本文為同步發布,點選這裡前往。

JUnit單元測試感悟

以前用dotnet的時候,曾經用過nunit,後來改用testdriven。但是由於專案不大,而且都是看得見摸的著的東西,直接就能看到執行介面,所以感覺用處並不是太大,也就是當作專案要求的規範來寫寫。現在,公司要求開發過程中必須用junit寫單元測試用例,即使以前的沒有寫測試用例的 也要補寫出來。寫...

JUnit單元測試感悟

以前用dotnet的時候,曾經用過nunit,後來改用testdriven。但是由於專案不大,而且都是看得見摸的著的東西,直接就能看到執行介面,所以感覺用處並不是太大,也就是當作專案要求的規範來寫寫。現在,公司要求開發過程中必須用junit寫單元測試用例,即使以前的沒有寫測試用例的 也要補寫出來。寫...

對指標的一點感悟

首先來看2張 這個程式是將二維陣列 a 裡面的元素輸出出來,但是左圖給指標賦值可以,但是右圖不行,為什麼?因為p是乙個陣列,對於陣列而言,p是乙個常量,常量的位址是固定的,所以p a相當於給常量賦值,這當然是不行的,語法上就是錯誤,而在左邊,相當於對陣列p裡的元素賦值,元素的位址雖然確定了,但是元素...