C# 使用SpecFlow建立BDD測試用例

2022-06-16 12:01:11

將自然語言編寫的測試用例轉換為可執行的測試,可以大大降低需求與開發之間的溝通成本,這是BDD(行為驅動開發)希望達到的效果。SpecFlow是.Net平臺的BDD工具,可以幫助我們建立面向BDD的測試用例。

首先,在Visual Studio 2022中安裝SpecFlow外掛。選擇選單擴充套件->管理擴充套件,然後搜尋SpecFlow:

點選下載,下載完成後,需要退出Visual Studio 2022,外掛會自動安裝。

我們編寫一個簡單的計算BMI(Body Mass Index身體質量指數)的功能作為測試目標,演演算法很簡單,輸入是身高和體重,計算公式是體重除以身高的平方。

再次啟動Visual Studio,建立一個類庫專案,名稱為CalBmi,編寫程式碼如下:

namespace CalBmi
{
    public class BmiCalculator
    {
        public Decimal Height { get; set; }

        public Decimal Weight { get; set; }

        public Decimal Bmi()
        {
            throw new NotImplementedException();
        }
    }
}

接下來,在解決方案中新增SpecFlow專案,選擇專案型別為SpecFlow:

專案名稱為TestBmi,選擇xUnit作為Test Framework:

建立完成後,專案的結構是這樣的:

然後,新增專案參照,將測試目標專案CalBmi新增到TestBmi的專案參照中:

到這裡,準備工作完成,現在可以開始寫測試用例了。在TestBmi中有一個範例模板,

程式碼是這樣的:

Feature: Calculator
![Calculator](https://specflow.org/wp-content/uploads/2020/09/calculator.png)
Simple calculator for adding **two** numbers

Link to a feature: [Calculator](TestBmi/Features/Calculator.feature)
***Further read***: **[Learn more about how to generate Living Documentation](https://docs.specflow.org/projects/specflow-livingdoc/en/latest/LivingDocGenerator/Generating-Documentation.html)**

@mytag
Scenario: Add two numbers
	Given the first number is 50
	And the second number is 70
	When the two numbers are added
	Then the result should be 120

這個測試的是兩個數位相加,我們照貓畫虎,編寫我們自己的測試用例,我們新增一個新的SpecFlow feature:

編寫程式碼如下:

Feature: 計算BMI

@mytag
Scenario: 根據身高體重計算BMI
	Given 身高1.75米
	And 體重70.00公斤
	When 計算BMI
	Then 結果應該是22.86

點選右鍵,選擇DefineSteps:

一個新的測試檔案被建立了:

程式碼如下:

using System;
using TechTalk.SpecFlow;

namespace TestBmi.StepDefinitions
{
    [Binding]
    public class 計算BMIStepDefinitions
    {
        [Given(@"身高(.*)米")]
        public void Given身高米(Decimal p0)
        {
            throw new PendingStepException();
        }

        [Given(@"體重(.*)公斤")]
        public void Given體重公斤(Decimal p0)
        {
            throw new PendingStepException();
        }

        [When(@"計算BMI")]
        public void When計算BMI()
        {
            throw new PendingStepException();
        }

        [Then(@"結果應該是(.*)")]
        public void Then結果應該是(Decimal p0)
        {
            throw new PendingStepException();
        }
    }
}

在這個類中,編寫測試,首先建立BmiCalculator的範例:

private readonly BmiCalculator _bmical = new BmiCalculator();

然後,改寫各個方法:

using CalBmi;
using System;
using TechTalk.SpecFlow;

namespace TestBmi.StepDefinitions
{
    [Binding]
    public class 計算BMIStepDefinitions
    {
        private readonly BmiCalculator _bmical = new BmiCalculator();
        private decimal _result;

        [Given(@"身高(.*)米")]
        public void Given身高米(Decimal p0)
        {
            _bmical.Height = p0;
        }

        [Given(@"體重(.*)公斤")]
        public void Given體重公斤(Decimal p0)
        {
            _bmical.Weight=p0;
        }

        [When(@"計算BMI")]
        public void When計算BMI()
        {
            _result=_bmical.Bmi();
        }

        [Then(@"結果應該是(.*)")]
        public void Then結果應該是(Decimal result)
        {
            _result.Should().Be(result); 
        }
    }
}

在測試管理器中執行這個測試:

與想象的一樣,測試沒有通過,因為我們沒有編寫實現程式碼,現在,修改BmiCalculator ,增加計算方法:

namespace CalBmi
{
    public class BmiCalculator
    {
        public Decimal Height { get; set; }

        public Decimal Weight { get; set; }

        public Decimal Bmi()
        {
            return Weight/Height/Height;
        }
    }
}

再次執行測試:

仍然沒有通過,問題是需要保留兩位小數,最後一位四捨五入,修改演演算法:

        public Decimal Bmi()
        {
            return System.Decimal.Round(Weight /Height/Height,2);
        }

再次執行測試,這次通過了:

在測試中給出了測試步驟和每個步驟花費的時間。