2011-02-05 203 views
25

我理解測試驅動開發背後的想法,首先編寫測試代碼,直到測試成功爲止。在我的工作流程中,它只是不適合我。單元測試的例子?

你可以舉一些例子,說明單元測試可以在前端或後端web開發環境中使用嗎?

+2

我建議尋找到這樣的回答: http://stackoverflow.com/questions/18601/best-practice-for-integrating-tdd-with-web-application-development – Herter 2011-02-05 22:58:36

+0

由於有無窮多的例子,這個問題太寬泛了。 – Raedwald 2016-09-30 08:42:45

回答

64

您沒有指定一種語言,所以我會盡量保持這種通用性。這很難,因爲用實際代碼表達概念要容易得多。

單元測試起初可能有點混亂。有時,如何測試某些東西,或者測試的目的是什麼,並不總是很清楚。

我喜歡將單元測試作爲測試單個小代碼的一種方式。

我使用單元測試的第一個地方是驗證某些方法的工作方式,就像我期望它適用於所有情況一樣。我剛剛爲我的網站寫了一個電話號碼的驗證方法。我接受來自123-555-1212,(123)555-1212等的任何輸入。我想確保我的驗證方法適用於所有可能的格式。如果沒有單元測試,我將被迫手動輸入每種不同的格式,並檢查表單是否正確發佈。這是非常乏味和容易出錯的。稍後,如果有人對手機驗證碼進行了更改,如果我們可以輕鬆檢查以確保沒有其他任何內容被破壞,那就太好了。 (也許我們增加了對國家代碼的支持)。所以,這裏有一個簡單的例子:

public class PhoneValidator 
{ 
    public bool IsValid(string phone) 
    { 
      return UseSomeRegExToTestPhone(phone); 
    } 
} 

我可以寫這樣的單元測試:

public void TestPhoneValidator() 
{ 
    string goodPhone = "(123) 555-1212"; 
    string badPhone = "555 12" 

    PhoneValidator validator = new PhoneValidator(); 

    Assert.IsTrue(validator.IsValid(goodPhone)); 
    Assert.IsFalse(validator.IsValid(badPhone)); 
} 

這2條斷言線將驗證該值從的IsValid()返回的真假分別。

在現實世界中,你可能會有很多很多很好的和壞的電話號碼的例子。我有大約30個電話號碼,我測試了。未來僅僅運行這個單元測試會告訴你,你的手機驗證邏輯是否被破壞。

我們也可以使用單元測試來模擬我們控制之外的事情。

單元測試應該獨立於任何外部資源運行。您的測試不應該依賴於存在的數據庫或Web服務可用。相反,我們模擬這些資源,所以我們可以控制他們返回的內容。例如,在我的應用程序中,我無法模擬註冊時被拒絕的信用卡。該銀行可能不會讓我提交數千張不良信用卡,以確保我的錯誤處理代碼是正確的。這裏有一些示例代碼:

public class AccountServices 
{ 
    private IBankWebService _webService = new BankWebService(); 

    public string RegisterUser(string username, string creditCard) 
    { 
     AddUserToDatabase(username); 

     bool success = _webService.BillUser(creditCard); 

     if (success == false) 
      return "Your credit card was declined" 
     else 
      return "Success!" 

    } 
} 

這是單元測試非常混亂和不明顯的地方。該方法的測試應該做什麼?首先,如果我們能夠檢查並看到如果計費失敗,那麼返回適當的錯誤消息將會非常好。事實證明,通過使用模擬,有一種方法。我們使用所謂的控制反轉。現在,AccountServices()負責創建BankWebService對象。讓我們讓這個類的調用者提供它雖然:

public class AccountServices 
{ 
    public AccountServices(IBankWebService webService) 
    { 
     _webService = webService; 
    } 

    private IBankWebService _webService; 

    public string RegisterUser(string username, string creditCard) 
    { 
     AddUserToDatabase(username); 

     bool success = _webService.BillUser(creditCard); 

     if (success == false) 
      return "Your credit card was declined" 
     else 
      return "Success!" 

    } 
} 

,因爲調用方負責創建BankWebService對象,我們的單元測試可以創建一個假的:

public class FakeBankWebService : IBankWebService 
{ 
    public bool BillUser(string creditCard) 
    { 
     return false; // our fake object always says billing failed 
    } 
} 

public void TestUserIsRemoved() 
{ 
    IBankWebService fakeBank = FakeBankWebService(); 

    AccountServices services = new AccountServices(fakeBank); 

    string registrationResult = services.RegisterUser("test_username"); 

    Assert.AreEqual("Your credit card was declined", registrationResult); 
} 

通過使用僞造的對象,任何時候我們的銀行的BillUser()被調用,我們的假對象將總是返回false。我們的單元測試現在驗證如果對銀行的呼叫失敗,RegisterUser()將返回正確的錯誤消息。

假設有一天你做一些改變,並錯誤小兵在:「成功」

public string RegisterUser(string username, string creditCard) 
{ 
    AddUserToDatabase(username); 

    bool success = _webService.BillUser(creditCard); 

    if (success) // IT'S BACKWARDS NOW 
     return "Your credit card was declined" 
    else 
     return "Success!" 

} 

現在,當您的結算失敗,你RegisterUser()方法返回。幸運的是,你有一個單元測試。單元測試現在將失敗,因爲它不再返回「您的信用卡被拒絕」。

用這種方法找到錯誤要比用手寫的不良信用卡填寫註冊表格更容易和更快,只是爲了檢查錯誤信息。

一旦你看到不同的模擬框架,你可以做更多更強大的事情。你可以驗證你的假方法被調用,你可以驗證一個方法被調用的次數,你可以驗證方法被調用的參數,等等。

我想一旦你理解了這兩個想法,你就會明白足以爲您的項目編寫大量的單元測試。

如果您告訴我們您正在使用的語言,我們可以更好地指導您。

我希望這會有所幫助。我很抱歉,如果其中一些令人困惑。如果事情沒有意義,我會清理它。