Specflow - 如何在场景中使用多个表的组合

Specflow - How to use combination of multiple tables in scenario

我正在使用 Specflow 执行 BDD 测试。我正在尝试在多个浏览器上测试我的导航菜单。特别要确保按钮在浏览器中显示。我不想为每个浏览器上的每个菜单项专门创建一堆测试,我也不想创建一个大的 table 遍历每个 browser/menu 项目组合。有什么方法可以指定 2 table,然后创建一个场景来执行两者的组合?

例如:

菜单项Table

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

浏览器Table

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

场景

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

预期的结果是,当这是 运行 时,它将 运行 9 次测试。

就我个人而言,我更喜欢征集所有组合。可能不需要一个或两个,或者您需要为每个指定特殊的期望值,等等:

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

如果你真的想创建完整的组合,我会使用带有示例的场景大纲:

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      |

更新:

在底层方法中,最后一个参数可以是 Table。所以在上面的例子中你可以得到 table 如下:

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

考虑到浏览器对于一个测试用例是不变的,我将按如下方式更改它:

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
}

如果您更喜欢强类型而不是 Table:

,您甚至可以为菜单项定义转换步骤
[Binding]
public class MyTransformations
{
    [StepArgumentTransformation]
    public MenuItem[] ToMenuItems(Table table)
    {
        return table.Rows.Select(row => new MenuItem(row[0])).ToArray();
    }        
}

现在您可以按如下方式定义 Given

[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));
}

When 步骤中自行进行测试。这就是你调用 DoTest 9 次后的方式:

[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);
}

最后,在 Then 步骤中,您可以断言您收集并存储到 DoTest 方法上下文中的可能错误。

您要编写的测试:

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

无论如何,您的目标应该是跨浏览器实现相同的功能,因此只需 运行 每个浏览器的整套测试。

在配置文件中,指定您想要 运行 的浏览器,并且在构建驱动程序时,从配置中检查您想要 运行 的浏览器。