[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