4
votes

I am using SpecFlow using .Net to Automating the UI. I have defined the Features and Scenarios for the same. My Question is scenarios are the dependent on other scenarios before executing the main scenarios I have to ensure that all the dependent data which is defined as a scenario's in the same feature file are created first so I put all those in the Background. So, when I am going to run next feature that also dependent on the same scenarios that we already created with the Feature 1st, that is already created or not? so we don't need to execute the same again.

So, is there any way to ensure that before running any scenario the background scenarios are already executed/created/present on the UI level.

2

2 Answers

4
votes

It sounds as though you are wanting to have a common background across several different feature files. There are at least two different ways to do this:

Composite Steps

One way to do this is what AlSki proposed, creating a composite step that calls many other steps. I won't redefine this here because he did a great job in his reply. You can call this composite step (step that calls many steps) from any scenario (or background) in any feature you like.

Tag Filtering on Hooks

Another approach is to use the Hooks defined in SpecFlow, like [BeforeScenario] to run some code before each scenario. You can use Tag Filtering (see the link for hooks) to specify which hook to run by adding the corresponding tag to the scenario or feature. Let me demonstrate with an example:

Let's say I have scenarios that execute using Selenium to drive a web browser, but not all my scenarios use Selenium. If I wanted to set up Selenium only for the scenarios that need it, I can create a BeforeScenario hook that only executes if the scenario has a tag @web.

Here is my feature file 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

Here is my step definitions file 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.
    }
}

For any scenario that has an @web tag, both BeforeAllScenarios() and BeforeWebScenario() will execute before the scenario does. For a scenario that doesn't have an @web tag, only the BeforeAllScenarios() method will execute.

In this way, you can just have a set of code run by applying a particular attribute to a scenario.

FYI: As of SpecFlow 1.9, you are unable to specify the order in which these hooks execute if more than one are specified.

When to use one or the other?

This depends on whether you are setting up a technical concern or a business concern.

Use tags to set up technical concerns

If you want to set up some technical aspect of your test that the business user doesn't need to be aware of, I would use the tag approach. A good example is the one I presented...setting up Selenium. The business user could care less what Selenium is, so it doesn't make sense to create a step in the scenario that sets that up.

Use composite steps to set up business concerns

If you need to specify the state of the system that a business user cares about (like a logged in user, or existing product data), then that should be another step in the scenario (or background). This is because the steps should include everything necessary to read and understand the behavior from the business perspective.

2
votes

I think you are asking about domains here, in that you've got a domain you've called background, and now you want to introduce another higher level domain called UI. So since I don't have enough information about your application I'll try and illustrate with another example.

Let's imagine we have a shop, we could write scenarios across many domains, such as stock control, opening up in the morning, giving change, and closing at night. This will probably mean that we have plenty of bindings such as WhenWeFillTheShelves(), WhenWeUnlockTheDoor(), WhenWeHaveAChangeInTheTill().

Now we come to deal with customer interaction, so we might want to write

Given the shop is ready for business

At this point here, I would write

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

In this way we have reused our lower level, more granualar domains to build up a higher level domain test, and you can guarantee everything is in the correct state every time.

I also suggest you read Dan North's Whose domain is it anyway