2010-10-19 53 views
5

在經歷了數月的挫折之後,以及在以前的開發者的巫毒娃娃中插入針的時間之後,我決定最好嘗試重構遺留代碼。UnitTesting一個返回一個複雜數據集的類

我已經訂購了Micheal Feather's book,我進入了Fowler's refactoring,我用DUnit做了一些示例項目。

所以,即使我不掌握這個主題,我覺得是時候採取行動,並將一些想法付諸實踐。

我工作的代碼中幾乎有100%的商業邏輯被困在用戶界面中,而且都是程序編程(有一些例外)。該應用程序開始如同快速&髒,並繼續如此。

現在編寫所有應用程序的測試對我而言是一個沒有意義的任務,但我想嘗試單元測試我需要重構的東西。

一個大的「TForm業務邏輯類」所做的一項複雜任務是讀取數據庫數據,進行一些計算並填充調度程序組件。我想刪除閱讀數據庫數據和計算部分,並分配給一個新的類這個任務。當然,這是一種改進當前設計的方法,它不是從頭開始的最佳方式,但我想這樣做,因爲這個新類返回的數據在其他方面也很有用,例如現在我有人要求發送調度程序數據的電子郵件通知。

所以爲了避免大量的複製和粘貼操作,我需要新的類。

現在調度程序從一個巨大的數據集(大小和數量的字段)中填充,可能第一個重構步驟可能是從新類中獲取數據集。但是,將來我最好使用一個新的類(比如TSchedulerData或其他一些不太需要調度器的名字)來管理數據,而不是有一個數據集,因爲我可以有一個TSchedulerData對象。

由於重構發生在小步驟和測試需要更好地重構我有點困惑如何繼續。

以下幾點是我不明白:

1)如何測試一個複雜的數據集?我應該運行工作應用程序,將一個結果集保存到xml中,然後在使用包含該xml數據的TClientDataSet的地方編寫測試?

2)我有多少要關心TSchedulerData?我的意思是我不是100%確定我會使用TSchedulerData,可能我會堅持使用數據集,無論如何,創建將在2周內丟棄的複雜測試對DUnitNewbee沒有吸引力。無論如何,可能這是它的工作原理。我無法想象沒有測試的情況下我會面對的錯誤數量。

最後說明:我知道有人認爲從頭開始重寫是一個更好的選擇,但這不是一個選項。 「該應用程序非常龐大,今天已售出,今天還需要新功能才能停止營業」。這就是我所知道的,無論如何,重構可以挽救我的生命並延長應用程序的生命。

回答

2

您的最終目標是將用戶界面,數據存儲和業務邏輯分爲不同的層。

使用自動測試框架測試UI非常困難。您最終希望儘可能多地從UI中分離業務邏輯。這可以使用各種模型/視圖/ *模式之一來完成。我更喜歡MVP被動視圖,它試圖使UI成爲一個界面。如果您使用的是數據集MVP,則監督控制器可能更適合。數據存儲需要有自己的一套測試,但是這些測試與單元測試不同(儘管你可以使用相同的單元測試框架),而且通常只有更少的測試。你可以逃避這一點,因爲大部分繁重的工作都是由第三方數據組件和dbms(在你的情況下是T * Dataset)完成的。這些是集成測試。基本上確保你的代碼與供應商的代碼很好。如果您在數據庫中定義了任何存儲過程,也是需要的。它們比單元測試慢得多,不需要經常運行。

業務邏輯就是你最想測試的東西。每個計算,循環或分支應該至少有一個測試(更多是可取的)。在傳統代碼中,這種邏輯經常直接觸及UI和數據庫,並在一個函數中執行多項操作。這裏提取方法是你的朋友。好的地方提取方法是:

for I:=0 to List.Count - 1 do 
begin 
    //HERE 
end; 

if /*HERE if its a complex condition*/ then 
begin 
    //HERE 
end 
else 
begin 
    //HERE 
end 

Answer := Var1/Var2 + Var1 * Var3; //HERE 

當你遇到這些提取點之一

  1. 決定你想要什麼樣的方法簽名看起來像你的新方法:方法的名稱,參數,返回值。
  2. 編寫一個測試調用它並檢查預期結果。
  3. 提取該方法。

如果一切順利,您將擁有至少一次通過單元測試的新提取方法。

德爾福的內置提取方法不給你任何方式來調整簽名,所以如果這是你自己的選擇,你將不得不做出並在提取後修復它。您還需要公開新方法,以便您的測試可以訪問它。有些人不願意公開私人公用事業方法,但在這個早期階段,你沒有什麼選擇。一旦你取得了足夠的進步,你就會開始看到你提取的一些實用方法屬於他們自己的類(在這種情況下,他們必須公開),而其他的可以被私有/保護和間接測試通過測試依賴於它們的方法。

隨着您的測試套件的增長,您需要在每次更改後運行它們,以確保您的最新更改沒有在其他地方發生。

本主題太大而無法完全覆蓋答案。你會發現你的問題絕大多數都是在這本書到達時才報道的。

2

我會說在接近嬰兒的步驟接近它。步驟#1:應該總是在你的入侵區域進行一些測試。TForm - 迴歸測試又名安全網。在你的情況下,感覺應用程序正在做什麼。從我讀到的,它似乎是一個數據轉換器。因此,花時間去了解所有輸入數據和相應輸出計劃的組合(或者最重要的是,如果不可行)。把它們寫成測試。確保所有測試都通過。

步驟#2:現在嘗試你的重構。在迴歸網絡的安全性下,將代碼塊移入內聚類等。

測試複雜的數據集 - 測試文件轉儲應該是最後的手段。但在這種情況下,它似乎是一個簡單的選擇開始。也許你可以用它自己的Equals()實現將它變成一流的域對象TSchedule。 推遲設計決策/更改,直到您在修改區域附近有一個可靠的迴歸測試套件。

+0

好的,謝謝。我所擔心的是編寫測試需要花費很多時間,因爲數據很複雜。文件轉儲很複雜,所以這是我第一次真正的單元測試嘗試,我擔心會失去一週的時間,並以不成功的測試結束。無論如何,我沒有其他地方可以開始,我的意思是,我需要改變這個代碼,所以我應該從這裏開始。 – LaBracca 2010-10-19 09:27:35

相關問題