2011-06-14 21 views
0

我正在學習SpecFlow並正在做一個簡單的Com-Sci標準FizzBu​​zz項目。 給定一個數字範圍 用Fizz替換3整除 用Buzz將5整除替換 用FizzBu​​zz替換3和5整除。如何在SpecFlow中爲多個相關需求創建功能

這是一個非常簡單的應用程序,但它確實爲我提出了一個問題。如何編寫特性來測試多個requiremts,這些requiremts全部來自API上的一個方法調用? 例如API調用將如下FizzBuzz.Replace(1, 100); 用替換法碼

public static string Replace (int min, int max) 
{ 
     if (IsDiv3 && IsDiv5) {...} 
     if (IsDiv3) {...} 
     if (IsDiv5) {...} 
     ... 
} 

我在SpecFlow特點如下:

Feature: FizzBuzz 
    In order to display Fizz Buzz in  range of numbers 
    As a user I want to be able to see Fizz Buzz replace certain numbers 

Scenario: Replace muliples of three and five with Fizz, Buzz or FizzBuzz 
    Given I have a range of numbers from 1 to 15 
    When I press Submit 
    Then the result should be 
    | Numbers | 
    | 1 | 
    | 2 | 
    | Fizz | 
    | 4 | 
    | Buzz | 
    | Fizz | 
    | 7 | 
    | 8  | 
    | Fizz | 
    | Buzz | 
    | 11  | 
    | Fizz | 
    | 13  | 
    | 14 | 
    | FizzBuzz| 

的另一個問題是如何使功能,如果我這樣做更有意義需要聚集一個功能中的所有需求。

編輯 我很努力地創建多個場景,因爲只要我創建第二個,第一個失敗。

scenario 1: replace divisable by 3 with Fizz 
Expected = 1 2 Fizz 4 5 Fizz 7 8 Fizz 10 11 Fizz 13 14 Fizz 
Actual = 1 2 Fizz 4 5 Fizz 7 8 Fizz 10 11 Fizz 13 14 Fizz (First test) 
Actual = 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 Fizz (Second test) 

然後做

Scenario 2: replace divisable by 5 with Buzz 
Expected = 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 Fizz 
Actual = 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 Fizz (Second test) 

第二個方案通過,但第一個現在無法在下一個場景。我不認爲打開API來做場景1,2,3是一個很好的應用程序設計。

感謝,

+0

我認爲其他人提供了很好的具體提示如何進行測試。我認爲道德是,如果您通過示例對API或規範進行TDD並不重要,則不應描述實際上不是「有效」的場景。您的場景1與功能的規格不符,因此它沒有幫助。是的,你應該努力爭取簡單的案例和不同的方面,但根據規範,情景應該都是有效的。如果規範本身隨着系統的發展而變化,那麼您需要相應地更新您的場景,這是另一個問題。 – 2011-06-16 09:28:45

回答

5

在郵件列表中查看您的郵件。如果你想分手費茲的測試,Buzz和FizzBu​​zz你可以改變你的規範創建方案,爲您實現的每個分支(即每一個「如果」):

Scenario: Replace multiples of three with Fizz 
    Given I have a range of numbers from 1 to 4 
    When I press Submit 
    Then the result should be 
    | Numbers | 
    | 1  | 
    | 2  | 
    | Fizz  | 
    | 4  | 

Scenario: Replace multiples of five with Buzz 
    Given I have a range of numbers from 4 to 5 
    When I press Submit 
    Then the result should be 
    | Numbers | 
    | 4  | 
    | Buzz  | 

Scenario: Replace multiples of three and five with FizzBuzz 
    Given I have a range of numbers from 14 to 16 
    When I press Submit 
    Then the result should be 
    | Numbers | 
    | 14  | 
    | FizzBuzz | 
    | 16  | 

在你的榜樣另一種看法是你的期望是用表格表示的(本質上是一個數組),但是你的結果是用一個字符串表示的。由於您在本例中使用SpecFlow進行API測試,因此我會嘗試通過更改規範或API來更緊密地對齊這兩個API。例如,考慮以下API更改「public static string [] Replace(int min,int max)」。那麼你的腳步會更容易寫的 - 是這樣的:

[Binding] 
public class FizzBuzzSteps 
{ 
    private int _min; 
    private int _max; 
    private string[] _results; 

    [Given(@"I have a range of numbers from (\d+) to (\d+)")] 
    public void GivenIHaveARangeOfNumbers(int min, int max) 
    { 
     _min = min; 
     _max = max; 
    } 

    [When(@"I press Submit")] 
    public void WhenIPressSubmit() 
    { 
     _results = FizzBuzz.Replace(_min, _max); 
    } 

    [Then(@"the result should be")] 
    public void ThenTheResultShouldBe(Table table) 
    { 
     for (var i = 0; i < table.RowCount; i++) 
     { 
      var expected = table.Rows[i]["Numbers"]; 
      var actual = _results[i]; 
      Assert.AreEqual(expected, actual); 
     } 
    } 
} 

HTH, 丹莫克

+0

感謝丹,這很有道理。現在我可以看到我將如何實現一個真實世界的例子。你會不會使用ScenarioContext來保持最小值,最大值和結果而不是專用字段? – skyfoot 2011-06-16 09:39:33

+0

是的,使用ScenarioContext對私有字段是一個好主意,那麼你可以在其他類的步驟定義中訪問它們 – MattStacey 2011-06-16 11:59:35

+0

同意你想使用ScenarioContext來存儲你的值。這將使得重構未來的步驟方法變得更加容易(即,它們不會被綁定到FizzBu​​zzSteps類的定義)。有一個問題,雖然...我使用的SpecFlow版本需要方法ScenarioContext.Get (鍵)中的類型參數T是一個對象(沒有值類型),所以我沒有去那條路線。但是,這可能已在新版本中得到修復。樂意效勞。感謝您的投票。 – 2011-06-16 19:32:28

0

當您運行顯示規格,specflow會提示你創建一個這樣的方法:

[Then(@"the result should be")] 
    public void ThenTheResultShouldBe(Table table) 

可以遍歷和檢索你的表中的值是這樣的:

[Then(@"the result should be")] 
    public void ThenTheResultShouldBe(Table table) 
    { 
     foreach (var row in table.Rows) 
     { 
      var numberValue = row["Numbers"]; // the name of the column specified 
     } 
    } 

由於如何使您的測試更有意義,我可以說的是我個人會將此測試分解成不同的場景。 我會做一個場景中的數字顯示爲除以3和除以5之外的其他數字。

+0

我有步驟並斷言測試場景,但只要我添加另一場景,第一次測試失敗,請參閱編輯問題 – skyfoot 2011-06-14 22:29:47

相關問題