2011-03-02 47 views
0

BDD場景中的給定語句是否工作或只驗證狀態?應該在BDD測試中給定的工作還是隻驗證狀態?

例如,考慮這個例子:「鑑於我在我登錄」

如果步驟定義用戶登錄或它應該只確認我在我登錄?

如果它應該只驗證我登錄,那麼我如何實際登錄?

+0

嗨。你有沒有從這個問題得出結論?我有一個類似的問題。我認爲另一個例子是:鑑於我在產品頁面上。我認爲它需要運行所有步驟才能達到該狀態,例如登錄並導航到產品頁面。在這種情況下,情況可能實際上閱讀發給我的登錄頁面/和我一起有效憑據登錄/我瀏覽到產品頁面。所以基本上我們的出發點始終是登錄頁面。這感覺不對,但... – 2012-02-03 11:52:41

回答

1

答案取決於你試圖測試什麼。這個例子聽起來像是黃瓜裏的東西,但是你使用了BDD這個術語。我將BDD與自下而上的單元測試聯繫起來。如果是這樣的話,我們假設你有一個類的認證類和一個用戶類。

用戶等級:

public class User : IUser 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public string Password { get; set; } 
} 

public interface IUser 
{ 
    int ID { get; } 
    string Name { get; } 
    string Password { get; } 
} 

鑑定者類:

public class Authenticator : IAuthenticator 
    { 
     public Authenticator() 
     { 
      //Initialize and acquire some authentication mechanism (db, service, file, etc..) 
     } 

     public bool IsLoggedIn(IUser user) 
     { 
      return true; 
     } 
     public bool LoginUser(IUser user) 
     { 
      //Do real login. 
      return true; 
     } 

     public bool LogoutUser(IUser user) 
     { 
      //Do real logout. 
      return true; 
     } 
    } 

    public interface IAuthenticator 
    { 
     bool LoginUser(IUser user); 
     bool LogoutUser(IUser user); 
    } 

UserActions類調用認證,管理權限等:

public class UserActions 
{ 
    private readonly IAuthenticator _authenticator; 
    private readonly IUser _user; 
    //private Permissions Permissions; 

    public UserActions(IUser user) 
     : this(new Authenticator(), user) 
    { } 

    public UserActions(IAuthenticator authenticator, IUser user) 
    { 
     _authenticator = authenticator; 
     _user = user; 
    } 

    public bool Login() 
    { 
     var result = _authenticator.LoginUser(_user); 
     return result; 
    } 

    public void Logout() 
    { 
     _authenticator.LogoutUser(_user); 
    } 
} 

有了這些類,我會嘗試以測試UserActions類在登錄方面的行爲(使用NUnit和MOQ)並註銷。在這個例子中,沒有工作已完成,但例如起見,想象一個更全面的實現:

[TestFixture] 
public class Tester 
{ 
    [Test] 
    public void CanLoginGoodUser() 
    { 
     IUser user = new User { ID = 1, Name = "Test1", Password = "good" }; 
     var authenticator = new Mock<IAuthenticator>(); 
     authenticator.Setup(a => a.LoginUser(user)).Returns(true); 

     var action = new UserActions(authenticator.Object, user); 
     action.Login(); 
     authenticator.Verify(a => a.LoginUser(It.Is<IUser>(u => u == user)), Times.AtLeastOnce()); 
    } 

    [Test] 
    public void WontLoginBadUser() 
    { 
     IUser user = new User { ID = 1, Name = "Test1", Password = "bad" }; 
     var authenticator = new Mock<IAuthenticator>(); 
     authenticator.Setup(a => a.LoginUser(user)).Returns(false); 

     var action = new UserActions(authenticator.Object, user); 
     action.Login(); 
     authenticator.Verify(a => a.LoginUser(It.Is<IUser>(u => u == user)), Times.AtLeastOnce()); 
    } 
} 

我真的不登錄,或註銷。我所做的就是利用接口提供預設的響應,以顯示類與消耗的類進行交互時的行爲。在這種情況下,它是驗證者和用戶對象。請注意,我沒有模擬用戶類,因爲在這一點上,沒有必要。

我相信其他人會用這種方法不以爲然,但是這是我目前做的。它適用於我,因爲它允許自下而上的測試,可靠的代碼覆蓋率以及與我的課程設計相關的分離問題。

1

在一個RSpec風格的語法,這是我認爲當你說「一個BDD」測試中,所謂「規定」將是一個「描述」或「上下文」塊負責獲取測試組件的一部分進入正確的狀態,並且不負責進行任何斷言或驗證組件在該狀態下的行爲。

「給定」會做設置你的組件的工作,並跟隨一個「它」或「應當」,這驗證了某些行爲。

describe ClassUnderTest do 
    describe "some feature" do 
    context "given that I am logged in" do 
     before do 
     sign_in Factory :user 
     end 
     it "has some behavior" do 
     #make some assertion about the ClassUnderTest's behavior 
     end 
    end 
    end 
end 

我覺得賈裏德描述構建BDD測試有好的結構,如果紅寶石和RSpec是對您有用:http://blog.carbonfive.com/2010/10/21/rspec-best-practices/

相關問題