BDD场景多依赖

时间:2012-10-10 07:36:55

标签: bdd specflow

我使用.Net来自动化UI的SpecFlow。我已经定义了相同的功能和方案。我的问题是在执行主要场景之前场景依赖于其他场景我必须确保首先创建在同一个特征文件中定义为场景的所有相关数据,因此我将所有这些都放在后台。那么,当我要运行下一个依赖于我们已经使用Feature 1st创建的相同场景的功能时,是否已经创建了?所以我们不需要再次执行相同的操作。

那么,有没有办法确保在运行任何场景之前已经在UI级别执行/创建/显示了后台场景。

2 个答案:

答案 0 :(得分:4)

听起来好像你想要在几个不同的功能文件中拥有一个共同的背景。至少有两种不同的方法:

复合步骤

这样做的一种方法是AlSki提出的,创建一个复合步骤,调用许多其他步骤。我不会在这里重新定义,因为他在答复中做得很好。您可以在任何您喜欢的功能中从任何场景(或背景)调用此复合步骤(调用许多步骤的步骤)。

挂钩上的标记过滤

另一种方法是使用SpecFlow中定义的Hooks,如[BeforeScenario],在每个场景之前运行一些代码。您可以使用标记过滤(请参阅钩子链接)通过将相应标记添加到方案或功能来指定要运行的挂钩。让我用一个例子来证明:

假设我有使用Selenium来驱动Web浏览器的场景,但并非所有场景都使用Selenium。如果我只想为需要它的场景设置Selenium,我可以创建一个BeforeScenario钩子,只有在场景有标签@web时才会执行。

以下是我的专题文件LoggingIn.feature

Feature: Logging In

@web
Scenario: Log In
    Given I am on the login page
    When I supply valid credentials
    Then I should be taken to the homepage

这是我的步骤定义文件StepDefinitions.cs

[Binding]
public class StepDefinitions
{
    [BeforeScenario("web")]
    public static void BeforeWebScenario()
    {
        // Code to startup selenium
    }

    [BeforeScenario]
    public static void BeforeAllScenarios()
    {
        // Code that executes before every scenario...regardless of tag.
    }
}

对于具有@web标记的任何方案,BeforeAllScenarios()BeforeWebScenario()都将在方案执行之前执行。对于没有@web标记的方案,只会执行BeforeAllScenarios()方法。

通过这种方式,您可以通过将特定属性应用于场景来运行一组代码。

FYI:从SpecFlow 1.9开始,如果指定了多个钩子,则无法指定这些钩子的执行顺序。

何时使用其中一种?

这取决于您是在设置技术问题还是业务问题。

使用标签设置技术问题

如果您想设置业务用户不需要注意的测试的某些技术方面,我会使用标记方法。一个很好的例子是我提出的......设置Selenium。业务用户可以不关心Selenium是什么,因此在设置它的场景中创建一个步骤是没有意义的。

使用复合步骤设置业务问题

如果您需要指定业务用户关心的系统状态(如登录用户或现有产品数据),那么这应该是方案(或后台)中的另一个步骤。这是因为这些步骤应该包括从业务角度阅读和理解行为所需的一切。

答案 1 :(得分:2)

我认为你在这里询问域名,因为你有一个你称之为后台的域名,现在你想引入另一个更高级别的域名UI。因为我没有足够的关于你的应用程序的信息,我将尝试用另一个例子说明。

让我们假设我们有一个商店,我们可以在许多领域编写场景,例如库存控制,早上开放,改变,晚上关闭。这可能意味着我们有很多绑定,例如WhenWeFillTheShelves()WhenWeUnlockTheDoor()WhenWeHaveAChangeInTheTill()

现在我们来处理客户互动,所以我们可能想写

Given the shop is ready for business

此时此刻,我会写

[Binding]
public void GivenTheShopIsReadyForBusiness()
{
    WhenWeFillTheShelves();
    WhenWeHaveChangeInTheTill();
    WhenWeUnlockTheDoor();
}

通过这种方式,我们重新使用了较低级别,更多粒度的域来构建更高级别的域测试,并且您可以保证每次都处于正确的状态。

我还建议您阅读Dan North's Whose domain is it anyway