TDD 先使用你的設計而不是先實現你的設計

2021-06-16 08:03:27 字數 3442 閱讀 8576

先使用你的設計而不是先實現你的設計----tdd

tdd(test driven development)測試驅動開發,這裡的測試可以理解為先使用,先寫測試就要求你站在**使用者的角度思考,而不是單純的作為乙個實現者;當你站在使用者的角度時,你會因為自己要使用他們,而想方設法的使自己的設計更有用、使自己的介面更一致.

同時先寫單元測試有助於消除過渡複雜的設計,因為程式設計師很容易走乙個極端,就是做一些複雜但是不必要的事情,我們應該記住乙個原則就是:如果不是真正的需要這個功能,那麼我們不應該實現他,那麼什麼時候我們才能知道這個功能是不是必要的功能呢,ok!直接使用他們,你不使用他們就永遠也不知道他是不是真的有用,一旦你先編寫實現**,你將強制自己保留這些**,並繼續使用他們,ok!接下來的問題就是:你的類越來越多,你的實現越來越負責,最後你自己也無法控制,一旦出了問題,你不得不從頭開始梳理你的**,一行一行的debug,反過來,如果你先使用他(先寫單元測試)你將深思熟慮將如何使用他,如何是他們更具有可用性和便利性,如何是自己的設計更加注重實效,從而簡化你的**,因為我們都知道好的設計並不是類越多約好

那麼如何做tdd

記住幾個原則

1.      開始的story設計一定是戰略性的設計而不是戰術性質的;

如何理解:就是說在做story設計的時候,你應該只是設計為了實現你的功能,你需要幾個類,每個類做什麼事情,而不應該具體是設計你的程式的方法、引數、字段或者物件之間如何互動,因為這些是你在做具體的實現的時候才去考慮的事情,說到這裡就不等不提醒大家應該走出乙個誤區:設計不是一開始就固定好的,他是隨著你的開發具體展開的;設計應該是正確的而不是精確的,設計應該是指導你向正確的方向前進,而不是標識具體的路線也不是操縱你,設計應該是滿足實現即可,而不是越詳細越好;

2.      設計是可以被改變的,不要讓開頭的設計束縛你,但改進之後的設計請知曉團隊的所有成員;

3.      如果不是真正的需要,請不要實現他;

5.      記住這個時候你是**使用者,你應該考慮怎麼去使用,請不要讓實現細節干擾你;

下面舉個小小的例子:

我接到乙個story是在datamodel中加入我們客戶被法院執行的的資料,這些資料報括:執行法院、立案時間、案號、執行標的(元)、案件狀態、身份證號碼以及資料獲取的時間,為了實現這個story我不得不設計乙個網頁爬蟲,根據客戶姓名和身份證資訊從人民法院的**上爬取資料;

基於系統現狀和法院**的資料結構我設計了以下幾個類及他們的基本功能:

customer:  客戶級別資訊封裝類

customerbaseinfoexecuteservice:   從json檔案中解析獲取客戶的基本資訊

customercourtdatafetchservice: 根據客戶的姓名和身份證資訊從人民法院**上爬取資料

customercourtdata:法院資料封裝類

fileservice:將結果儲存為json檔案

ok,下面我先來使用這些類,也就是寫我的單元測試:

public void testcustomer(){

assertnotnull(newcustomer());

customercustomer = new customer();

string customername = 「張三」;

string cardnum = 「888888888888888」;

customer.setcustomername(customername);

customer.setcardnum(cardnum);

assertequals(customer.getcustomername(),customername);

你可能還會做這樣的考慮,因為身份證號碼是有格式,是不是要驗證一下呢?

記住我們的原則------如果不是真正的需要,請不要實現他;

我們從資料**去考慮這個問題,客戶的身份證資訊的源頭是crm,中間並為經過再次計算,也就是說我們的源頭已經給我們做了這樣的事情,我們並不需要在做這種重複的事情;

ok,接下來我來使用customerbaseinfoexecuteservice:

public void test customerbaseinfoexecuteservice(){

filefile = new file(「src/test/resources/file1.log」);

customercustomer = customerbaseinfoexecuteservice.execute(file);

assertnotnull(customer);

assertequals(customer,getcustomername(),」易衛國」);

assertequals(customer.getcardnum();」 33012519600602641x」)

上面是基本的流程,思考一下,作為這個類的輸入file,如果他是不存在應該怎麼,如果檔案格式不符合json的格式會這樣,也許你要考慮這麼多使用者我是不是不應該乙個使用者乙個檔案等等,於是你還應該有諸如下面的使用或者修改

list< customer> list = customerbaseinfoexecuteservice.execute(file)

assertnotnull(list);

assertequals(list.size() ,100);

好了,現在我已經使用了我所有在戰略設計階段設計的類,我要開始編碼了,這個時候就展開我的設計,我考慮我的物件互動等問題……

以下我的一些體驗:

1.      我對上次那個顧問這句話持保留意見:tdd是高手的事情;我覺得tdd應該是幫助我們去思考我們的業務,思考我們**的可用性和便利性,它重在堅持,重在積累;

2.      tdd的**和story提交驗收或者**checkin的時候的測試是不等同的,tdd幫助你將設計展開,但是你還是要在**check in之前進行測試,這時候的測試不僅僅是單元測試,有可能是你在瀏覽器位址列裡輸入個這樣的url:

然後驗證一下資料庫或者是頁面上的值是不是期望的值,也有可能是你在頁面上點乙個按鈕等,當然也可能是更多的單元測試;

3.      tdd的**是具體實現**的守護**(就像守護執行緒一樣),一旦你去修改**守護**就會盯著你,告訴你這樣該是不是對的(當然請不要為了迎合你的錯誤去修改單元測試的**,除非這個單元測試本身是錯誤的,對與錯由客戶/業務說了算);

4.      tdd幫助我們思考哪些是真正需要的功能,幫助我們真正的做事,做正確的事,而不是發上一天的事情去實現乙個並不需要的功能這也是敏捷的目的之一;

5.      敏捷幫助我們盡快的獲取反饋,在問題剛剛出現的時候解決他,你可以將你的tdd**告訴所有的團隊程式,請他們進行codereview,這個時候往往問題就出來了,而不是當你的實現寫了99%的時候,發現其實你不需要這樣做,你只要每次給個標識位問題就解決了,那麼你為了這99%的實現所發的兩條甚至一周的時間就是浪費;

6.      不要壓縮你寫tdd的時間,如果你發現這個story的tdd不好寫,就是說你開始設計出來的類不要使用,那要麼是你的設計錯誤,要麼是客戶給了你乙個不明確的需求,但絕對不是tdd錯了;

如何正確的使用你的時間

你是否時常會焦慮時間過的很快,沒時間學習,本文將會分享一些個人的見解。在工作中我們時常會花很多時間去 debug,但是你是否發現很多問題最終只是你基礎不紮實或者文件沒有仔細看。基礎是你技術的基石,一定要花時間打好基礎,而不是追各種新的技術。一旦你的基礎紮實,學習各種新的技術也肯定不在話下,因為新的技...

如何說服你的同事使用TDD

tdd test driven development 也就是我們常說的 測試驅動開發 是由 kent beck 在1996年提出的概念。tdd這個術語,經常被人掛在嘴邊,然而真正在專案實施,卻寥寥無幾。是tdd對開發者要求太高?還是tdd根本就不值得去做?非也。為了讓大家對tdd有乙個具體而親切的...

使用測試驅動開發 TDD 的困難險阻

測試驅動開發 tdd 是個好東西,但是我們在專案中真正使用它時卻有種 想說愛你不容易 的感覺。這是為什麼呢?此處應用小瀋陽語氣 1 專案組傳統與習慣。專案組從來沒使用過tdd,並且已經寫了n年 發布了幾個版本。這時忽然要求大家使用tdd開發,難免會有些不習慣。tdd要求先寫出測試,然後才能寫 而大家...