0

私は SpecFlow を学んでおり、単純な Com-Sci 標準の FizzBu​​zz プロジェクトを行っています。与えられた数値の範囲 3 で割り切れる数を Fizz に置き換えます。 5 で割り切れる数を Buzz に置き換えます。 3 と 5 で割り切れる数を FizzBu​​zz に置き換えます。

これは非常に単純なアプリケーションですが、私には疑問が生じました。API の 1 つのメソッド呼び出しからすべてが起動される複数の要件をテストするための機能を作成するにはどうすればよいですか? たとえば、API 呼び出しは次のようFizzBuzz.Replace(1, 100); になり、Replace メソッド コードは次のようになります。

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|

さらなる問題は、すべての要件を 1 つの機能にまとめる必要がある場合、その機能をより意味のあるものにする方法です。

編集 2 つ目のシナリオを作成するとすぐに最初のシナリオが失敗するため、複数のシナリオの作成に苦労しています。

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)

2 番目のシナリオはパスしますが、最初のシナリオは失敗します。シナリオ 1、2、3 を実行するために API を開くことは、アプリにとって良い設計になるとは思いません。

ありがとう、

4

2 に答える 2

5

メーリングリストであなたのメッセージを見ました。Fizz、Buzz、および FizzBu​​zz のテストを分割したい場合は、仕様を変更して、実装の各ブランチ (つまり、各「if」) のシナリオを作成できます。

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       |

あなたの例のもう 1 つの観察結果は、期待はテーブル (基本的には配列) で表されますが、結果は文字列で表されることです。この例では SpecFlow を使用して API テストを行っているため、仕様または API を変更して、これら 2 つをより密接に調整しようとします。

たとえば、次の 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、ダン・モーク

于 2011-06-15T22:49:30.317 に答える
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 で割った数字で示される数字のシナリオを 1 つ実行します。

于 2011-06-14T17:53:11.933 に答える