简体   繁体   中英

Specflow - How to use combination of multiple tables in scenario

I am using Specflow to perform BDD tests. I am trying to test my navigation menu on multiple browsers. Particularly making sure that buttons are showing up accross browsers. I do not want to create a bunch of tests for each menu item specifically on each browser and I do not want to create a large table that goes over every browser/menu item combination. Is there any way to specify 2 tables and then create a single scenario that performs the combinations of both?

For example:

Menu Items Table

| menuItem |
| Home     |
| About    |
| Contact  |

Browsers Table

| browser |
| Chrome  |
| Firefox |
| IE      |

Scenario

Scenario Outline: I can see menu item
    Given I navigate to the "/" page using <browser>
    Then I can see the menu item <menuItem>

The expected result is that when this is run it would run 9 tests.

Personally I prefer enlisting all of the combinations. It can happen that one or two is not needed or you need to specify special expected values for each, etc.:

Scenario: Flat scenario
    Given I have the following config:
    | menuItem | browser |
    | Home     | Chrome  |
   #| Home     | IE      | - ok, this is not needed
    | Home     | Firefox |
    | About    | Chrome  |
    | About    | IE      |
    | About    | Firefox |
    | Contact  | Chrome  |
    | Contact  | IE      |
    | Contact  | Firefox |
    Then something happens

If you really want to create full combinations I would use Scenario Outline with examples:

Scenario Outline: Combined scenario
    Given I have the following config:
    | MenuItem | Browser   |
    | Home     | <browser> |
    | About    | <browser> |
    | Contact  | <browser> |
    Then something happens

    Examples:
    | browser |
    | Chrome  |
    | Firefox |
    | IE      |

Update:

In the underlying method the last parameter can be a Table . So in the example above you can get the table as follows:

[Given(@"I have the following config:")]
public void InitFromConfiguration(Table table)
{
    // now the table has MenuItem and Browser columns
}

Considering browser is constant for one test case I would change it as follows:

Scenario Outline: Even better combined scenario
    Given I have the following items in the specified <browser>:
    | MenuItem |
    | Home     |
    | About    |
    | Contact  |
    When I test the browser with the given menuItems
    Then I have no errors

    Examples:
    | browser |
    | Chrome  |
    | Firefox |
    | IE      |

[Given(@"I have the following items in the specified (.*):")]
public void InitFromConfiguration(string browser, Table menuItems)
{
    // now the browser comes from the Examples and menuItems has 3 rows
}

You can even define a transform step for menu items if you prefer strong types instead of Table :

[Binding]
public class MyTransformations
{
    [StepArgumentTransformation]
    public MenuItem[] ToMenuItems(Table table)
    {
        return table.Rows.Select(row => new MenuItem(row[0])).ToArray();
    }        
}

And now you can define your Given as follows:

[Given(@"I have the following items in the specified (.*):")]
public void InitFromConfiguration(string browser, MenuItem[] menuItems)
{
    ScenarioContext.Current.Set(browser, nameof(browser));
    ScenarioContext.Current.Set(menuItems, nameof(menuItems));
}

Do the test itself in the When step. This is how you will call DoTest 9 times after all:

[When(@"I test the (.*) with the given (.*)")]
public void InitFromConfiguration(string browserKey, string menuItemsKey)
{
    var browser = ScenarioContext.Current.Get<string>(browserKey);
    var menuItems = ScenarioContext.Current.Get<MenuItem[]>(menuItemsKey);

    // TODO: in DoTest you can collect and save the possible errors in the context
    foreach (MenuItem mi in menuItems)
        DoTest(browser, mi);
}

And finally in the Then step you can assert the possible errors you collected and stored into the context in the DoTest method.

The test you want to write:

Scenario: I can see menu items
    Given I navigate to the "/" page
    Then I can see the menu items:
         | Home     |
         | About    |
         | Contact  |

You should be aiming for the same functionality across browsers anyway, so simply run the entire suite of tests for each browser.

In a config file, specify the browser you want to run and when you are building the driver, check which browser you want to run from the config.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM