結果與期望比對,是測試程式碼中最重要的一個步驟,就是用它來取代人眼比對,有關物件比對 91哥的文章有非常詳細的介紹:
https://dotblogs.com.tw/hatelove/2014/06/06/how-to-assert-two-collection-equal
https://dotblogs.com.tw/hatelove/2016/03/28/compare-object-equality-with-expected-objects
當測試程式碼用的是複雜型別,會比對型別中的屬性狀態(值),用它來決定是否通過驗證,最直接的方式就是跑迴圈一個一個比,這樣做不是很聰明,也不夠快,太費力
我會使用以下物件來完成我的工作
- FluentAssertions
- SpecFlow
在這裡我分享我常用的比對方式...
開發環境
- Windows 10 Enterprise x64 CHT
- VS 2015 Update2 Eng
- FluentAssertions 4.9
- SpecFlow 2.1
FluentAssertions
Nuget 上的 FluentAssertions 提供了相當多的比對方式,其中複雜型別的比對可通過 ShouldBeEquivalentTo | ShouldAllBeEquivalentTo 方法實現
它可以
Anonymous Type Compare
Anonymous Collection Type Compare
Anonymous and Name Type Compare
[TestMethod]
public void 具名型別集合和具名型別集合比較()
{
var expected = new List<Product>()
{
new Product { ID=1,Name="pen",Price=2.22m,Remark = "我爸的筆"},
new Product { ID=2,Name="book",Price=4.96m ,Remark = "我爸的書"},
};
var actual = new List<Product>()
{
new Product { ID=1,Name="pen",Price=2.22m,Remark = "我爸的筆"},
new Product { ID=2,Name="book",Price=4.96m ,Remark = "我爸的書"},
};
expected.ShouldBeEquivalentTo(actual);
}
在某些情況下,我只比某些欄位,其餘欄位不重要,我不要比,expected 沒有 Remark 這個欄位,測試仍然亮綠燈
[TestMethod]
public void 匿名型別集合和具名型別集合比較()
{
var expected = new[]
{
new { ID=1,Name="pen",Price=2.22m },
new { ID=2,Name="book",Price=4.96m },
};
var actual = new List<Product>()
{
new Product { ID=1,Name="pen",Price=2.22m,Remark = "我爸的筆"},
new Product { ID=2,Name="book",Price=4.96m ,Remark = "我爸的書"},
};
expected.ShouldBeEquivalentTo(actual);
}
FluentAssertions 只會比 expected 存在的項目,不理會 actual
[TestMethod]
public void 匿名型別和具名型別比較()
{
var expected = new { ID = 1, Name = "pen", Price = 2.22m };
var actual = new Product { ID = 1, Name = "pen", Price = 2.22m, Remark = "我爸的筆" };
expected.ShouldBeEquivalentTo(actual);
}
比對單一物件用 ShouldBeEquivalentTo
比對集合物件用 ShouldAllBeEquivalentTo (也可比對單一物件)
SpecFlow
有關資料庫的驗證,我會採用 SpecFlow 來完成多欄位的驗證,而不是 FluentAssertions,它描述多欄位需求,較容易閱讀;驗證時,也只會根據 Then 所描述的欄位下去比對(部分比對)。
Scenario: SpecFlow比較部分屬性
Given Product資料表應有以下資料
| ID | Name | Price | Remark |
| 1 | pen | 2.22 | 我爸的筆 |
| 2 | book | 4.96 | 我爸的書 |
Then 我預期應在Product資料表得到以下資料
| ID | Name | Price |
| 1 | pen | 2.22 |
| 2 | book | 4.96 |
以下程式碼沒有真的操作資料庫,重點是 SpecFlow 的比對方法 table.CompareToSet(products)
[Given(@"Product資料表應有以下資料")]
public void GivenProduct資料表應有以下資料(Table table)
{
var products = table.CreateSet<Product>();
ScenarioContext.Current.Add("products", products);
}
[Then(@"我預期應在Product資料表得到以下資料")]
public void Then我預期應在Product資料表得到以下資料(Table table)
{
var products = ScenarioContext.Current.Get<IEnumerable<Product>>("products");
table.CompareToSet(products);
}
比對單一物件用 table.CompareToInstance()
比對集合物件用 table.CompareToSet()
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET