2009-11-05 49 views
1

所以我開始寫的我寫有用的方法類庫,拿起多年來,我會用兩個代碼例子入手,然後問我具體的問題:如何開始使用單元測試?總共n00b的問題,想法?

我還喜歡說這是而不是其他一些的副本,「我在哪裏開始單元測試問題。」

檢查網絡連接(不上網,只是netwok)

public static Boolean IsNetworkConnected() 
    { 
     Boolean ret = false; 
     try 
     { 
      String HostName = System.Net.Dns.GetHostName(); 
      System.Net.IPHostEntry thisHost = System.Net.Dns.GetHostEntry(HostName); 
      String thisIpAddr = thisHost.AddressList[0].ToString(); 

      ret = thisIpAddr != System.Net.IPAddress.Parse("127.0.0.1").ToString(); 
     } 
     catch (Exception) 
     { 
      return false; 
     } 
     return ret; 
    } 

而且我IsValiEmail方法(注意,我沒有寫的正則表達式)

public const String MatchEmailPattern = @"^(([\w-]+\.)+[\w-]+|([a-zA-Z]{1}|[\w-]{2,}))@" 
     + @"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\." 
     + @"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|" 
     + @"([a-zA-Z]+[\w-]+\.)+[a-zA-Z]{2,4})$"; 


    public static bool IsValidEmail(string email) 
    { 
     if (email != null && email != string.Empty) 
      return Regex.IsMatch(email, MatchEmailPattern); 
     else 
      return false; 
    } 

所以,我的問題是怎麼做的我測試這些方法實際上工作,顯然我想開始更多我的代碼比這些快速示例更復雜的單元測試。

如果可能,我想避免安裝其他工具/框架,但我願意接受您的想法。

更新

應該這個新的單元測試代碼(通過鏈接已經發布)住?在同一個大會?單獨的組裝?

回答

5

看看這本書。 The art of unit testing。維基頁面有很多很棒的資源。

+0

+1。這是一本很好的起始書。 – TrueWill 2009-11-05 03:53:42

+0

+1同意,也是一本很棒的書,一旦你掌握了基礎知識,但想獲得可維護的測試套件。 – Mathias 2009-11-05 04:00:08

+0

幾乎任何羅伊奧謝羅夫用單元測試做的事情都是金子! – 2009-11-05 04:23:47

0

您可以從Junit開始,您可以使用模擬框架(如mockito)來模擬包含使用框架的部分代碼。但要使用模擬框架,您需要將使用外部框架的代碼的一部分分離爲單獨的類或接口,並使用模擬框架來模擬外部依賴。

另外在你的代碼中,你正在使用「==」運算符來進行字符串比較。


ret = thisIpAddr != System.Net.IPAddress.Parse("127.0.0.1").ToString();

但是,你應該使用 「等於」 方法用於字符串比較。

+3

這是一個C#問題,而不是Java問題。 – TrueWill 2009-11-05 03:55:24

+0

OOPS,正如您所指出的,我完全錯過了這不是Java問題。感謝您的更正 – sateesh 2009-11-05 05:17:09

0

與Asaph一致,NUnit是最廣泛使用的框架。這就是說,如果你不想使用額外的框架,VStudio Professional確實包含了內置的單元測試工具。
我建議把你的測試放在同一個解決方案中,在一個單獨的項目中,這樣你就不必運送你的組裝測試。
你的第一種情況實際上不是單元測試最明顯的,因爲你的類有一個外部依賴性,這將很難複製:顯然,如果類測試機器連接,結果本身將取決於狀態的機器。換句話說,如果測試失敗,您不知道是因爲您的代碼,還是因爲您的代碼無法控制某些內容。這些情況通常是通過Mocking來實現的,但如果你不熟悉單元測試,這可能不是最簡單的事情!
第二種情況是一個好得多的起點;基本上你必須創建有效和無效的地址,並將它們傳遞給你的方法,並檢查結果是什麼。

1

對於你要研究引進依賴倒置,這樣就可以模擬出這些依賴和控制時,該方法返回true,當它返回false代碼的第一位。

對於第二個我想創造一些NUnit的測試,每個傳遞有效或無效的電子郵件和驗證返回正確的結果。您可以通過爲每個想要測試的電子郵件創建一個測試或創建一個測試作爲行測試(可以使用NUnit 2.5+)來完成此操作。

至於在測試應該住....以及他們生活在同一個組件或其他組件...最佳實踐,此刻,似乎是把它們放在一個單獨的程序。如果您有一個名爲MyProject的項目,那麼您可以爲您的單元測試創​​建一個名爲MyProject.Tests ....的項目,並且作爲額外的附加功能,您可以將集成測試放入名爲MyProject.Integration.Tests的另一個程序集中。

2

你當然可以做單元測試沒有一個框架 - 只是做一個應用程序與運行測試「測試」按鈕。但是,我發現使用現有框架更好 - 它們的設置允許您輕鬆添加測試,查看成功/失敗並自動運行測試。 Nunit很好,或者真的,任何事情都會做。 MSTest是可以的,如果你有它自帶的Visual Studio版本的話。

IsValidEmail應該很容易測試:用空考「」,一個有效的電子郵件和無效的電子郵件。然後戴上一頂黑帽子,嘗試偷偷溜地偷走垃圾:你能把它弄壞嗎?但是由於這個功能只對其輸入有效,所以測試起來很容易。

IsNetworkConnected很難測試。您調用GetHostName和GetHostEntry,並且無法控制它們返回的內容。這使得很難檢查所有可能的模式。單元測試對你施加強大的壓力,將邏輯與數據檢索分開。這裏的一個選擇是傳入IPHostEntry。當然,這會使你的異常陷阱不太有用,並將其中的一部分推送給調用者。

您可以構建一個函數來爲您調用GetHostName和GetHostEntry,然後將委託傳遞給應用程序中的實際代碼,並在您的測試中傳遞一個虛擬*代碼。在某種程度上,這種策略的成本高於其提供的價值 - 您必須自己作出判斷,並且不要在不產生價值的工作上浪費精力。

* Mock Objects技術的關注者將注意到,您不應該嘲笑GetHostName和GetHostEntry,因爲您不擁有它們。如果你有一個嘲弄的框架,並希望使用它,請隨意;只是不要誤以爲他們的設計方法使用他們的工具。

2

測試IsNetworkConnected

肖恩·麥克米蘭是正確的,他的反應不存在測試IsNetworkConnected方法太多好處的。它並沒有封裝太多的邏輯,只包含不值得抽象的依賴。但是,讓我們假裝由於某種原因單元測試該方法非常重要。下面是我會去的方式:

public static Boolean IsNetworkConnected(IIPAddressProvider ipAddressProvider) 
    { 
     Boolean ret = false; 
     try 
     { 
      IPAddress thisIpAddr = ipAddressProvider.GetIPAddressOFLocalHost(); 
      ret = thisIpAddr.ToString() != System.Net.IPAddress.Parse("127.0.0.1").ToString(); 
     } 
     catch (Exception) 
     { 
      return false; 
     } 
     return ret; 
    } 

這樣做之後,我會寫下面的單元測試:從IIPAddressProvider的模擬

  • 返回null ip地址從

    • 拋出異常IIPAddressProvider的模擬
    • 從IIPAddressProvider的模擬中返回127.0.0.1
    • 從IIPAddressPro的模擬中返回不同於127.0.0.1的IPAddress vider

    測試IsValidEmail

    有一個在編寫單元測試這種方法有一定價值。您需要嘗試正面,負面和邊界測試案例。單元測試也是白盒測試的形式。從你的方法來看,顯然你需要在做單元測試的同時練習方法的前提條件和正則表達式。這裏重要的是要鍛鍊正則表達式。該方法中沒有很多代碼路徑。在我看來,你需要編寫上面提到的測試用例場景。此外,在生產代碼中使用它之前,應使用一些用於進行正則表達式驗證的第三方工具。

    應該在哪裏測試代碼位於

    在我看來,它應該始終位於從生產代碼不同的裝配。這是最好的選擇。