關於測試的多樣且奇幻的形狀
金字塔、蜂巢、獎盃和單元測試的意義
2021 年 6 月 2 日
最近推特等社群網站上對於團隊應如何分配測試工作展開熱烈討論。特別是,Tim Bray 提出令人信服的論點,主張應認真看待自動化測試。熟悉我文章的人都知道我非常認同他的觀點。
他在文章中提出的一個觀點與以下兩張圖片有關


這兩個「變形斑點」都是對較早的 測試金字塔 圖片的回應

這些圖片的重點在於指出我們應投入多少精力在各種測試類型上,特別是單元測試和廣泛測試之間的平衡。金字塔主張應將大部分測試工作放在單元測試上,而蜂巢和獎盃則表示應將較少量的精力放在單元測試上,並主要專注於整合測試。
對於此討論,我遇到的第二個最大的問題是不透明,因為不清楚人們如何看待單元測試和整合測試之間的差異。
即使以大多數軟體術語的模糊標準來看,「單元測試」和「整合測試」這兩個術語一直以來都相當模糊。我最初的理解是,它們主要是組織問題。讓我們回到大型瀑布式軟體專案的時代。我花了好幾個月時間開發一段程式碼。我可能是單獨開發,也可能是在一個小團隊中開發。無論如何,我將這段程式碼視為一個概念單元,我們可以與其鄰近的程式碼相對獨立地開發。完成編碼後,我們可以將其移交給單元測試團隊,然後由他們單獨測試該單元。花一兩個月讓這些測試運作後,我們可以將其與鄰近的程式碼整合,並針對系統的較大部份,甚至整個系統執行整合測試。關鍵區別在於,單元測試會孤立測試我的/我們的程式碼,而整合測試則會測試我們的程式碼如何與個別開發的程式碼搭配運作。
如今,許多人會在 Xunit 測試工具系列中接觸到單元測試,該系列由 Kent Beck 開發,是 極限編程 的一部分。Kent 使用「單元測試」來表示開發人員在日常工作中編寫的測試。
程式設計師編寫單元測試,以便他們對程式運作的信心可以成為程式本身的一部分。客戶編寫功能測試,以便他們對程式運作的信心也可以成為程式的一部分。
請注意,在 Kent 的原始表述中,「單元測試」是指程式設計人員編寫的任何內容,而不是由獨立的測試團隊編寫的內容。在 C3 中,當我們撰寫單元測試時,我們通常會專注於單一類別的行為。但是,我們會設定一個測試固定裝置,使用所有必要的相依性建立該物件,以便它可以執行其方法。這些其他物件也會執行,但我們會假設在這個測試中,所有其他程式碼都正確運作(而且通常其他程式碼有其自己的測試)。
我記得關於「單元測試」的這個用法有相當多的討論。一位測試專家強烈批評 Kent 使用這個用法。我們問他如何定義單元測試,他的回答類似於「在我的訓練課程的第一個早上,我涵蓋了 24 種不同的單元測試定義」。
從 XP 啟發的單元測試的早期開始,就有人不喜歡「單元測試」這個術語,並建議改用「微測試」或「程式設計人員測試」等名稱。
對許多人來說,這方面最大的問題是這些相依物件。如果我正在測試一個訂單物件,而它與一個客戶物件協作,那麼我對訂單物件的測試可能會因為客戶物件中的錯誤而失敗。這導致了撰寫單元測試的不同風格,其中任何協作物件都將被模擬、存根或其他類型的 測試替身 取代。從那以後,我發現將這些 單元測試 的風格描述為社交和獨自一人很有用。 [1]

與此區別交織在一起的是兩個 XP 單元測試實務流派的發展,我稱之為經典和模擬。經典 XP 單元測試遵循我們最初使用的社交方法,而模擬風格則偏好獨自測試。
因此,回到金字塔與蜂巢,當我閱讀蜂巢和類似形狀的倡導者時,我通常會聽到他們批評過度使用模擬,並談論導致各種問題。由此我推斷他們對「單元測試」的定義具體來說就是我所謂的獨自單元測試。類似地,他們對整合測試的概念聽起來很像我所謂的社交單元測試。這使得金字塔與蜂巢的討論變得沒有意義,因為我聽過的所有測試金字塔描述都將單元測試視為社交和/或獨自的。
此語意圖片因 整合測試 的定義而變得更加混淆,這使得「單元測試」看起來定義嚴謹。此處的重點是,當有人開始討論各種測試類別時,請深入了解他們對其字詞的定義,因為他們可能不會使用與您之前閱讀的人相同的方式。
如果您仔細閱讀我的文章,您會注意到我之前說過,關於單元測試和整合測試缺乏明確性的問題是我對蜂巢/金字塔討論的第二大問題。我的最大問題可以用以下引言很好地總結。
人們喜歡爭論要撰寫哪種類型的測試以及要撰寫多少比例,但這只會分散注意力。幾乎沒有團隊撰寫表達性的測試來建立明確的界線、快速且可靠地執行,並且僅在有用的原因下才會失敗。專注於此。
註腳
1: Jay Fields 提出了「單獨」和「社交」這兩個術語