BDD場景中的給定語句是否工作或只驗證狀態?應該在BDD測試中給定的工作還是隻驗證狀態?
例如,考慮這個例子:「鑑於我在我登錄」
如果步驟定義用戶登錄或它應該只確認我在我登錄?
如果它應該只驗證我登錄,那麼我如何實際登錄?
BDD場景中的給定語句是否工作或只驗證狀態?應該在BDD測試中給定的工作還是隻驗證狀態?
例如,考慮這個例子:「鑑於我在我登錄」
如果步驟定義用戶登錄或它應該只確認我在我登錄?
如果它應該只驗證我登錄,那麼我如何實際登錄?
答案取決於你試圖測試什麼。這個例子聽起來像是黃瓜裏的東西,但是你使用了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());
}
}
我真的不登錄,或註銷。我所做的就是利用接口提供預設的響應,以顯示類與消耗的類進行交互時的行爲。在這種情況下,它是驗證者和用戶對象。請注意,我沒有模擬用戶類,因爲在這一點上,沒有必要。
我相信其他人會用這種方法不以爲然,但是這是我目前做的。它適用於我,因爲它允許自下而上的測試,可靠的代碼覆蓋率以及與我的課程設計相關的分離問題。
在一個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/
嗨。你有沒有從這個問題得出結論?我有一個類似的問題。我認爲另一個例子是:鑑於我在產品頁面上。我認爲它需要運行所有步驟才能達到該狀態,例如登錄並導航到產品頁面。在這種情況下,情況可能實際上閱讀發給我的登錄頁面/和我一起有效憑據登錄/我瀏覽到產品頁面。所以基本上我們的出發點始終是登錄頁面。這感覺不對,但... – 2012-02-03 11:52:41