[C#.NET][SpecFlow] 使用 SpecFlow.Table 處理多筆資料驗証
續上篇,http://www.dotblogs.com.tw/yc421206/archive/2014/12/22/147756.aspx
SpecFlow 除了能夠傳入單欄資料,也能傳入多筆多欄,SpecFlow API 會自動幫你將 Scenario 的表格轉強型別,這會用到以下方法,要先using TechTalk.SpecFlow.Assist 命名空間
轉型:
- 建立單筆資料:Table.CreateInstance()
- 建立多筆資料:Table.CreateSet()
驗証:(比 CollectionAssert 好用)
-
比較單筆資料:Table.CompareToInstance()
- 比較多筆資料:Table.CompareToSet()
這裡還用了兩個 Attribute,Before /After Scenario,在方法上加上即可,SpecFlow 就知道要調用它
- 開始執行 Scenario 前:[BeforeScenario()]
- 完成 Scenario 後:[AfterScenario()]
當 Scenario 需求單傳入的參數是用表格型態製作,轉成程式碼的時候參數要用 Table 型別去接,方法裡做的動作只有 1.轉型、2.存放
Scenario 如下:
Scenario: 模糊查詢產品
Given 我輸入查詢資料
| ProductName |
| 余小章's |
And 預計資料應有
| ProductName | UnitPrice | Discontinued |
| 余小章's C# book | 29 | false |
| 余小章's VB book | 21 | false |
| 余小章's ASP.NET book | 22 | false |
When 我按下查詢
Then 查詢結果應該有
| ProductName | UnitPrice |
| 余小章's C# book | 29 |
| 余小章's VB book | 21 |
| 余小章's ASP.NET book | 22 |
我使用了北風資料庫的 Product Table,所以欄位的命名是依照 Table 所設計,稍微解釋一下我的 Scenario,
準備環境:
Given 我輸入查詢資料:查詢關鍵字『余小章's』
And 預計資料應有:準備將資料插到實際的資料庫,這代表我們準備的假資料,資料庫沒有
執行動作:
When 我按下查詢:調用被測端方法
驗證結果是否符合預期:
Then 查詢結果應該有:從資料庫撈資料出來與期望的結果比對
程式碼如下:
- Product 是我從 EF Code First from Database 轉過來的
https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.SpecFlowTable/Simple.Utility/Products.cs - ScenarioContext.Current 用來存放 Product Instance
public void Given我輸入查詢資料(Table table)
{
var product = table.CreateInstance<Product>();
ScenarioContext.Current["product"] = product;
}
DAO 會用到 EF,不過它不是本篇的重點,所以請到以下連結查看
https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.SpecFlowTable/Simple.Utility/BusinessFlowDAO.cs
public void Given預計資料應有(Table table)
{
var products = table.CreateSet<Product>();
this._dao.Insert(products);
this._dao.Commit();
}
public void When我按下查詢()
{
var instance = ScenarioContext.Current.Get<Product>("product");
var condition = instance.ProductName;
var actual = this._dao.GetLikeProducts(condition);
ScenarioContext.Current.Set(actual, "actual");
}
public void Then查詢結果應該有(Table expected)
{
var actual = ScenarioContext.Current.Get<IEnumerable<Product>>("actual");
expected.CompareToSet<Product>(actual);
}
確保資料庫乾淨,開始執行Scenario的前後都把資料刪除,這樣才能確保測試程式運行正確
public void Before()
{
if (this._dao == null)
{
this._dao = new BusinessFlowDAO();
}
using (NorthwindDbContext db = new NorthwindDbContext())
{
var query = db.Products.Where(p => p.ProductName.Contains("余小章's")).ToList();
if (query.Any())
{
db.Products.RemoveRange(query);
db.SaveChanges();
}
}
}
[AfterScenario()]
public void After()
{
using (NorthwindDbContext db = new NorthwindDbContext())
{
var query = db.Products.Where(p => p.ProductName.Contains("余小章's")).ToList();
if (query.Any())
{
db.Products.RemoveRange(query);
db.SaveChanges();
}
}
}
最後運行測試,得到綠燈,代表我的被測端程式的邏輯與我預期的無誤
文章出自:http://www.dotblogs.com.tw/yc421206/archive/2014/12/25/147796.aspx
專案位置:https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.SpecFlowTable/
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET