0

我尝试使用 cucumber/gherkin(实际上是 specflow)测试的业务场景是,给定 Web 表单上的一组输入,我提出请求,并且需要确保(在某些条件下)结果是返回时,一个特定的字段没有改变(在其他条件下,它确实)。例如

鉴于我在数据输入屏幕上当我选择“不更新 frobnicator”并提交表单并显示结果然后 frobnicator 没有更新

我将如何编写“fobnicator 未更新”步骤?

一种选择是在“我提交表单”之前运行一个步骤,其内容类似于“我记得 frobnicator 的值”,但这有点垃圾 - 这是实现细节的可怕泄漏。它分散了测试的注意力,并且不是业务描述的方式。事实上,任何人看到这样的台词,我都必须解释它。

有没有人对如何更好地实现这一点有任何想法,理想情况下是书面的?

4

2 回答 2

1

我不同意前面的答案。你觉得你想写的小黄瓜文字可能是对的。我将对其进行一些修改以使其成为When正在测试的特定操作。

Given I am on the data entry screen
And I have selected "do not update frobnicator"
When I submit the form
Then the frobnicator is not updated

您如何断言结果将取决于您的程序如何更新 frobnicator,以及为您提供的选项.. 但为了证明这是可能的,我假设您已经将数据访问层与 UI 分离并且能够模拟它 - 因此监控更新。

我使用的模拟语法来自 Moq。

...

private DataEntryScreen _testee;

[Given(@"I am on the data entry screen")] 
public void SetUpDataEntryScreen()
{
    var dataService = new Mock<IDataAccessLayer>();
    var frobby = new Mock<IFrobnicator>();

    dataService.Setup(x => x.SaveRecord(It.IsAny<IFrobnicator>())).Verifiable(); 
    ScenarioContext.Current.Set(dataService, "mockDataService");

    _testee = new DataEntryScreen(dataService.Object, frobby.Object);
}

这里要注意的重要一点是,给定的步骤设置了我们正在测试的对象以及它需要的所有东西......我们不需要一个单独的笨重步骤来说“我有一个我要去的 frobnicator记住”——这对利益相关者不利,对您的代码灵活性不利

[Given(@"I have selected ""do not update frobnicator""")]
public void FrobnicatorUpdateIsSwitchedOff()
{
    _testee.Settings.FrobnicatorUpdate = false;
}

[When(@"I submit the form")]
public void Submit()
{
    _testee.Submit();
}

[Then(@"the frobnicator is not updated")]
public void CheckFrobnicatorUpdates()
{
    var dataService = ScenarioContext.Current.Get<Mock<IDataAccessLayer>>("mockDataService");

    dataService.Verify(x => x.SaveRecord(It.IsAny<IFrobnicator>()), Times.Never);
}

根据您的情况调整安排、行动、断言的原则。

于 2012-01-27T21:48:18.037 回答
0

想想你将如何手动测试它:

Given I am on the data entry screen
And the blah is set to "foo"
When I set the blah to "bar"
And I select "do not update frobnicator"
And I submit the form
Then the blah should be "foo"
于 2011-05-31T10:26:27.963 回答