[SpecFlow] 一個 Step 呼叫多個 Step

當你想要聚焦,減少 Scenario 的 Step Definition 時,可以合併他們,提高 Scenario 的可讀性;但伴隨來的副作用就是細節被隱藏到 Step.cs 測試程式碼,從 Sceario 讀不出來,團隊內若都很了解細節,這樣倒是一個不錯的做法

開發環境

  • VS 2019 16.0.3
  • SpecFlow 3.0.220

加法的 Scenario 有 4 個 Step Definition,這是原本的寫法

Scenario: 加法
	Given I have entered 50 into the calculator
	And I have also entered 70 into the calculator
	When I press add
	Then the result should be 120 on the screen

 

Step.cs 測試程式碼如下

[Binding]
[Scope(Feature = "計算機V1")]
public class 計算機V1Steps : Steps
{
    [Given(@"I have entered (.*) into the calculator")]
    public void GivenIHaveEnteredIntoTheCalculator(decimal firstNumber)
    {
        this.ScenarioContext.Set(firstNumber, "firstNumber");
    }
 
    [Given(@"I have also entered (.*) into the calculator")]
    public void GivenIHaveAlsoEnteredIntoTheCalculator(int secondNumber)
    {
        this.ScenarioContext.Set(secondNumber, "secondNumber");
    }
 
    [When(@"I press add")]
    public void WhenIPressAdd()
    {
        var firstNumber  = this.ScenarioContext.Get<decimal>("firstNumber");
        var secondNumber = this.ScenarioContext.Get<decimal>("secondNumber");
        var calculation  = new Calculation();
        var actual       = calculation.Add(firstNumber, secondNumber);
        this.ScenarioContext.Set(actual, "actual");
    }
 
    [Then(@"the result should be (.*) on the screen")]
    public void ThenTheResultShouldBeOnTheScreen(decimal expected)
    {
        var actual = this.ScenarioContext.Get<decimal>("actual");
        Assert.AreEqual(expected, actual);
    }
}

 

接著我把 Step Definition 合併,變成一個 Step Definition,只剩下 Given

Scenario: 呼叫加法
	Given I press add and the result should be success

 

回顧一下合併前,有 4 個 Step Definition


 

我需要在這個 Step.cs 測試程式碼再去呼叫別的 Scenario Step,這裡用的是 Given、When、Then,也就是 Scenario 描述中的 Step Definition

[Given(@"I press add and the result should be success")]
public void GivenIPressAddAndTheResultShouldBeSuccess()
{
    decimal firstNumber  = 70;
    decimal secondNumber = 50;
    decimal expected     = 120;
    this.Given($@"I have entered {firstNumber} into the calculator");
    this.Given($@"I also have entered {secondNumber} into the calculator");
    this.When(@"I press add");
    this.Then($@"the result should be {expected} on the screen");
}

 

再看另一個例子,我用 Table,寫出加法的 Scenario

Scenario: 加法
	Given I have entered two number into the calculator
		| FirstNumber | SecondNumber |
		| 50          | 70           |
	When I press add
	Then the result should be 120 on the screen

 

Step.cs 測試程式碼 把 Table 轉成強型別物件進行處理;當然你要直接處理 Table 也是沒有問題的

[Binding]
[Scope(Feature = "計算機V2")]
public class 計算機V2Steps : Steps
{
    [Given(@"I have entered two number into the calculator")]
    public void GivenIHaveEnteredTwoNumberIntoTheCalculator(Table table)
    {
        this.ScenarioContext.Set(table.CreateInstance<TwoVariable>(), "variable");
    }
 
    [When(@"I press add")]
    public void WhenIPressAdd()
    {
        var variable    = this.ScenarioContext.Get<TwoVariable>("variable");
        var calculation = new Calculation();
        var actual      = calculation.Add(variable.FirstNumber, variable.SecondNumber);
        this.ScenarioContext.Set(actual, "actual");
    }
 
    [Then(@"the result should be (.*) on the screen")]
    public void ThenTheResultShouldBeOnTheScreen(decimal expected)
    {
        var actual = this.ScenarioContext.Get<decimal>("actual");
        Assert.AreEqual(expected, actual);
    }
}

 

合併 Step Definition 如下

Scenario: 呼叫加法
	Given I press add and the result should be success

 

回顧一下合併前,有 3 個 Setp,由於要合併的 Step 有用到Table,所以要手動建立跟合併前一樣的 Table

 

Step.cs 測試程式碼手動建立 Table,然後呼叫 Scenoario Step Definition

[Given(@"I press add and the result should be success")]
public void GivenIPressAddAndTheResultShouldBeSuccess()
{
    var      expected = 120d;
    string[] header   = { "FirstNumber", "SecondNumber" };
    string[] row      = { "50", "70" };
    var      table    = new Table(header);
    table.AddRow(row);
 
    this.Given(@"I have entered two number into the calculator", table);
    this.When(@"I press add");
    this.Then($@"the result should be {expected} on the screen");
}

 

參考
https://specflow.org/documentation/Calling-Steps-from-Step-Definitions/

當你想要聚焦,減少 Scenario 的 Step 時,可以合併他們,提高 Scenario 的可讀性;但伴隨來的副作用就是細節被隱藏到 Step.cs 測試程式碼,從 Sceario 讀不出來,團隊內若都很了解細節,這樣倒是一個不錯的做法

 

範例

https://github.com/yaochangyu/sample.dotblog/tree/master/Test/Specflow3/Lab.CallOtherStep
 

 

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo