0

我正在学习 SpecFlow,并且正在做一个简单的 Com-Sci 标准 FizzBu​​zz 项目。给定一个数字范围 用 Fizz 替换能被 3 整除 用 Buzz 替换能被 5 整除 用 FizzBu​​zz 替换能被 3 和 5 整除。

这是一个非常简单的应用程序,但它确实给我提出了一个问题。如何编写功能来测试多个需求,这些需求都是从 API 上的一个方法调用中触发的?例如,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|

另一个问题是,如果我确实需要将所有需求集中在一个功能中,如何使该功能更有意义。

编辑 我正在努力创建多个场景,因为一旦我创建了第二个场景,第一个场景就会失败。

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 对应用程序来说是一个好的设计。

谢谢,

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       |

您的示例中的另一个观察结果是您的期望以表格(本质上是一个数组)表示,但您的结果以字符串表示。由于您在此示例中使用 SpecFlow 进行 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,丹·莫克

于 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 的数字。

于 2011-06-14T17:53:11.933 回答