tdd 測試驅動開發

2021-08-14 13:07:13 字數 2838 閱讀 2587

這是一張影響圖:

當壓力越大時,所做的測試就會越少。測試越少,犯的錯就會越多,就會感到更大的壓力。這是乙個會造成情境越來越糟的迴圈。

我們用事先編寫的測試來驅動開發,因為測試先於開發,所以我們在感到壓力時,就執行這些測試,它們會馬上給我們一種系統良好的感覺,而且會減少開發出錯的次數,進而減少我們的壓力,從而跳出上面的迴圈。

讓測試盡可能快地執行。

盡量在小範圍內進行。

測試之間互不干擾,這意味著所有的測試都是不依賴於順序的。這樣就不會因為測試順序的不同而出現的許多古怪問題。這對開發人員提出了更高的要求,因為必須把問題分解為彼此正交的小問題,這樣做的好處是,每個測試會變得更加簡單而且可以快速執行,物件也會變成漂亮的「高內聚、低耦合」的類物件。

寫一張包含所有要編寫的測試清單,可以記錄在一張紙上。這張表記錄的就是我們要去實現的測試。

在編寫要被測試的**之前也編寫測試**。

從測試完成時能夠通過的斷言(形如assertequals())開始編寫測試**。

使用讓人容易理解的資料,記住,你寫的**以後會有人閱讀、有人維護的!

在以下的情況下,使用真實世界中的資料很有效:

讓測試包含預期和實際的結果,努力讓它們容易理解,因為還要讓其他人閱讀的,所以要留下盡可能多的線索。

使用乙個公開的 api 介面或者包時,可以編寫乙個測試來驗證這個 api 工作是否符合我們的期望。這樣做有兩點好處: 

* 可以讓我們更好地理解它。 

* 如果測試無法執行,可能是使用的問題,也可能是 api 本身的問題,測試會讓問題更快地暴露出來。

當你感覺到累的時候,休息一下。適當的放鬆會讓大腦的思維得到解放。

保持不可執行-》可執行-》重構的節奏對可持續的成功非常重要。付出額外的努力來保持這種節奏是值得的。當之前的測試**突然要求幾處變化時,可能的原因是我們之前所寫的測試**太大了,這就需要重構把這些測試**,嘗試把它變成幾個子測試**咯。

如果乙個測試依賴於昂貴而且複製的資源物件,那麼就建立乙個這些資源的模擬物件。典型的例子是資料庫,建立它很耗時間,而且它也是開發過程中錯誤產生的溫床。

解決辦法是在大多數時間裡不使用真正的資料庫,而是寫乙個像資料庫一樣的物件,或者採用乙個第三方開源的資料庫模擬 api,讓它僅僅駐留在記憶體中。這樣做,不僅帶來了高效的效能,而且還很可靠,可讀性也很好。

如果擔心模擬物件與現實物件的行為不一致,那麼可以使用對實際物件適用的一系列測試來測試模擬物件,從而減少這種風險。

丟擲乙個異常物件來測試**中處理錯誤的邏輯。因為我們的安全假設是,沒有被測試過的**是不會正常工作的,處理錯誤的邏輯也是**的一部分,所以我們也要進行測試。

假設要測試當檔案系統滿了以後,系統會發生什麼。可以花費很多時間建立許多大檔案來填滿整個檔案系統,這種方法費時費力。另一種方法是採用偽實現,即丟擲乙個異常:

public

class

fullfile

extends

file

public

boolean

createnewfile() throws ioexception

}

如果在試圖提交時,發現有許多測試沒有通過。最可能的原因是你可能對剛剛編碼的東西沒有完全理解,因此最簡單的辦法就是把之前做過的工作推倒重來。

因為許多測試沒有通過,注釋掉一些測試**是嚴格禁止的,這是一種不負責任的、偷懶的表現。

測試不能通過的時候,先返回乙個常量,讓測試執行通過。然後通過重構把這個常量逐步轉換為用變數表示的表示式。偽實現就像登山時在頭頂上方釘乙個登山用的鋼錐,它會讓你安心,讓你覺得繼續爬上去是安全的。

使用偽實現有兩個主要原因:

三角法的含義是:只有當我們有有了兩個或兩個以上的測試用例時,才能對功能進行抽象。

只有在不能確定是否需要對要實現的功能是否已經進行了正確的抽象時,才使用這個方法。

顯明實現含義是:如果我們知道要些什麼,並且能夠很快地完成,那就直接實現吧。

顯明實現只是第二選擇。因為你在追求自身的完美,而這是不可能的!所以記住時刻保持不可執行-》可執行-》重構的編碼習慣!

寫乙個布林表示式傳遞給乙個斷言,來判斷我們的工作是否執行正常。形如assertequals(...)

在 junit 中,可以為斷言傳遞更詳細的資訊,形如asserttrue("測試用例 1",false)

如果幾個測試都存在一些通用物件,這種重複是不好的,因為:

所以我們把幾個測試都需要的通用物件,轉變為例項變數,然後在setup()中初始化這些物件。

使用teardown來釋放資源,這樣能避免重複,原因和初始化固定設施是一樣的!

不論測試**中發生了什麼,甚至是丟擲乙個異常,xunit 也能保證最後呼叫teardown

我們需要測試期望的異常,只有捕獲到這些異常,異常測試才算通過。

我們只關心捕獲我們所期望的異常,因此,如果丟擲了乙個非期望的異常,我們也會從 xunit 框架中得到通知。

可以把所有的測試合成乙個測試套件,每個包乙個套件,一次性執行所有的測試。

一般經過一段時間的適應,開發人員都會傾向於採用小步驟進行開發。可以利用 ide 的自動重構功能來提高重構的速度。

應該測試這些東西:

記住,只測試我們編寫的**,除非有足夠的理由,否則不要測試其他**的**。

這些是設計存在的缺陷的特徵:

如果存在兩個測試互為冗餘,根據以下原則進行刪除:

lifeware 的乙個跟保險有關專案就是採用 tdd 進行開發的。共歷時 4 年,有 40 人參與了這個專案。編寫了大約 500,000 行**(其中有一半是測試**),有 4000 個能夠在 20 分鐘內能夠執行完畢的測試。所以現在有信心了吧 o(∩_∩)o~

TDD 測試驅動開發

test driven development 測試驅動開發是敏捷開發中的一項核心實踐和技術,也是一種設計方 tdd的原理是在開發功能 之前,先編寫單元測試用例 測試 確定需要編 寫什麼產品 tdd雖是敏捷方法的核心實踐,但不只適用於xp extreme programming 同樣可以適用於其他開...

測試驅動開發TDD

測試驅動開發 testdriven development,tdd 的基本思路是通過測試推進整個的開發工作,並不只是單純的測試工作。利用這種測試方法時,若要完成某個功能,某個類,首先不是編譯正式的 而是先編寫測試 考慮其如何使用 如何測試。然後在對其進行設計 正式編碼。t dd具有很強的目的性,是在...

TDD測試驅動開發

tdd是test driven development的簡稱,意為測試驅動開發。測試驅動開發是一種軟體的開發方法。它指在編寫某個功能的 之前先編寫測試 然後編寫能使測試通過的功能 逐個測試來實現軟體的開發。測試驅動開發有助於提高 質量和開發進度。測試驅動開發一般步驟 1.新增乙個測試 2.執行所有測...