2009-11-19 18 views
4

我已經看到了對我來說兩種BDD方法。差取決於的「時」的位置:BDD和「何時」的位置

在方法1中,當是本說明書的一部分:

AnEmptyStack.isNoLongerEmptyAfterPush 

在純的「給定的時,然後」術語是這樣的:

「給定一個空棧,當它被推入時,它不再是空的。「

所以「時」,是本說明書的方法的一部分:

isNoLongerEmptyAfterPush(){ 
    stack.push(anObject); 
    Assert.notEmpty(stack); 
} 

在方法2中,當在類級別被定義。也就是說,通常在設置中調用何時。

class WhenAnEmptyStackIsPushed(){ 

    setup(){ 
     stack.push(); 
    } 

    public void thenItIsNotEmpty(){ 
     assert(stack.notEmpty()) 
    } 
} 

是否有首選方法?就純粹的行爲測試而言,第二種選擇似乎更適合我,因爲測試夾具的重點在於行爲。

但是,爲了便於測試,我傾向於第一種方法。我在測試中發現的大部分疼痛是設置。也就是說,我有一個特別的狀態得到SUT。一旦進入該狀態通常只有一行代碼來實際調用它的某些行爲。因此,每個類有多個行爲(即每個設置上下文)利用了該類的一次性設置。

所以,我正在尋找想法。一種方法比另一種更受歡迎嗎?

回答

1

根據您的測試框架,您也許可以擁有兩全其美。

當我創建了一套圍繞SUT測試中,我首先聲明一個類,將包裹一整套規範,那麼抽象類:

public class SomethingDoerSpecs 
{ 

    public abstract class concern : observations_for_a_sut_with_a_contract<IDoSomething,SomethingDoer> 
    { 
     // here I can define setup that will be common to all subsequent tests 
     context c =() => ... 
    } 

    public class When_asked_to_do_something : concern 
    { 
     context c =() => 
     { 
      // setup specific to this context goes here 
     }; 

     because b =() => sut.DoSomething(); 

     it should_open_a_database_connection = 
      () => mock_db_connection.was_told_to(x => x.Open()); 

     it should_set_the_result_value_to_true = 
      () => sut.Result.should_be_true(); 

     // etc. 
    } 

    public class When_asked_to_do_something_but_the_database_is_unavailable 
     : When_asked_to_do_something 
    { 
     context c =() => 
     { 
      // additional context 
     }; 

     because b = doing(() => sut.DoSomething()); 

     it should_throw_a_custom_exception =() => 
     { 
      exception_thrown_by_the_sut.should_not_be_null(); 
      exception_thrown_by_the_sut 
       .should_be_an_instance_of<CouldNotDoSomethingException>(); 
     }; 

    } 
} 

這只是爲了說明的測試類常常是嵌套的,所以你仍然可以做「大」當......和重用你已經通過當您需要更大的背景下特異性繼承成立以前的狀態。當然,你必須確保你的框架將重置設置斷言之間的設置。

順便說一句,我在這裏展示的整個委託語法來自Jean-Paul Boodhoo的DevelopWithPassion.Bdd庫,您可以在Github上找到它。

0

我認爲你的替代方案2是更可取的方案。在我看來,每個測試類別應該在一個狀態下設置SUT,然後每個測試方法然後對該對象進行觀察。我認爲,如果你爲課堂增加更多的觀察數據,這會更有意義。如果每個觀察結果都是唯一的,並且觀察沒有額外的行動,我想你會看到所有的觀察結果如何自然地屬於一起

如果你去替代1你不分組的意見,因爲他們觀察到相同的對象(州)的不同方面,而是因爲他們有一些共同的初始狀態要重新使用。不要組測試代碼重用,組測試,因爲他們屬於一個整體,並使用其他手段來重用代碼作爲輔助類/方法,甚至繼承(即所有協議棧相關的類可以從創建一個空Stack類繼承)。