如何在SpecFlow中为多个相关需求创建要素
本文关键字:需求 创建 SpecFlow | 更新日期: 2023-09-27 17:59:02
我正在学习SpecFlow,并正在做一个简单的Com Sci标准FizzBuzz项目。给定一系列数字将可被3整除的项替换为Fizz将可被5整除的项替换为Buzz将可被3和5整除的部分替换为FizzBuzz。
这是一个非常简单的应用程序,但它确实给我提出了一个问题。如何编写功能来测试多个需求,这些需求都是从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会是一个很好的应用程序设计。
谢谢,
在邮件列表上看到您的邮件。如果你想拆分Fizz、Buzz和FizzBuzz的测试,你可以更改你的规范,为你的实现的每个分支创建一个场景(即每个"如果"):
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,Dan Mork
当您运行所显示的规范时,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的数字。