系列目錄 <https://www.cnblogs.com/tylerzhou/p/11204826.html>
Nunit里提供了豐富的數(shù)據(jù)測試功能,雖然Xunit里提供的比較少,但是也能滿足很多場景下使用了,如果數(shù)據(jù)場景非常復(fù)雜,Nunit和Xunit都是無法勝任的,有不少測試者選擇自己編寫一個(gè)數(shù)據(jù)提供程序,但是更建議使用AutoFixture框架,一是因?yàn)樽约汗ぷ髦袑懙耐皇菫榱私鉀Q某個(gè)或者部分問題,只能隨著業(yè)務(wù)邏輯的擴(kuò)展才能不斷的健壯起來,二是這樣的框架往往缺少良好文檔,主要由核心開發(fā)者口口相傳,這就導(dǎo)致后來者遇到不明白了功能就去問核心開發(fā)者,影響這些開發(fā)者的其它工作.
下面介紹一下Xunit里的數(shù)據(jù)提供方式.
InlineData
InlineData相當(dāng)于Nunit里的TestCase,用注解的方式給測試方法提供數(shù)據(jù).
我們通過以下代碼片段了解它的基本用法
[Theory] [InlineData(1, 2)] [InlineData(5, 9)] public void Test1(int x,int y)
{ int result = x + y; Assert.Equal(x + y, result); }
以上方法與普通測試方法相比最大的區(qū)別是它使用的是Theory注解,而不是fact注解.使用Theory注解的方法必須提供相應(yīng)的參數(shù),否則會(huì)報(bào)編譯錯(cuò)誤.
以上測試我們提供了兩組InlineData,這樣在測試運(yùn)行的時(shí)候測試方法就會(huì)根據(jù)這些數(shù)據(jù)生成兩個(gè)方法實(shí)例.同Nunit里的表現(xiàn)行為相似.
MemberData
MemberData顧名思義,就是成員數(shù)據(jù),它類似于Nunit里的TestCaseSource
但是不同的是Xunit的MemberData的數(shù)據(jù)提供者必須是當(dāng)前測試類的成員,測試數(shù)據(jù)提供者和測試方法耦合在一塊可能不是太好的設(shè)計(jì),如果需要大量測試數(shù)據(jù),建議使用AutoFixture.
數(shù)據(jù)提供者之屬性提供數(shù)據(jù)
通過屬性提供測試數(shù)據(jù)適應(yīng)于一些比較簡單的場景,這些數(shù)據(jù)是簡單的,確定的.
下面看一個(gè)示例
[Theory] [MemberData(nameof(UnitTest1.ProvideData))] public void Test1(int
x,int y) { int result = x + y; Assert.Equal(x + y, result); } public static
IEnumerable<object[]> ProvideData { get { yield return new object[] { 3, 4 };
yield return new object[] { 5, 9 }; yield return new object[] { 11, 13 }; } }
以上代碼中,測試方法和數(shù)據(jù)提供者必須位于同一個(gè)類中,并且數(shù)據(jù)提供者必須是一個(gè)公開的,靜態(tài)的屬性.并且它的集合元素類型必須是Object類型.像以上Test1方法雖然需要的是int類型參數(shù),但是提供者類型也必須是object類型,而不能是具體類型.
以上數(shù)據(jù)提供屬性一共yield了三組數(shù)據(jù),因此測試方法會(huì)生成三個(gè)測試實(shí)例.
數(shù)據(jù)提供者之方法提供數(shù)據(jù)
[Theory] [MemberData(nameof(UnitTest1.ProvideData))] public void Test1(int
x,int y) { int result = x + y; Assert.Equal(x + y, result); } public static
IEnumerable<object[]> ProvideData() { yield return new object[]{3,4 }; yield
return new object[] {5, 9}; yield return new object[] { 11, 13 }; }
你可能會(huì)感覺以上方法和屬性并沒太大的區(qū)別,其實(shí)方法的功能更為強(qiáng)大,因?yàn)閷傩詿o法動(dòng)態(tài)指定參數(shù),而方法可以,我們可以指定方法接收動(dòng)態(tài)運(yùn)行時(shí)需要的參數(shù),然后在MemberData的構(gòu)造函數(shù)里傳入?yún)?shù)來動(dòng)態(tài)獲取數(shù)據(jù).
數(shù)據(jù)提供者之成員提供數(shù)據(jù)
成員提供數(shù)據(jù)可以把外部對象作為本類成員,然后給測試方法提供數(shù)據(jù).外部對象須繼承自TheoryData.
我們定義一個(gè)MyDataprovider
public class MyDataprovider<TData1,TData2>:TheoryData<TData1,TData2> { public
MyDataprovider(IEnumerable<TData1> dataSource1,IEnumerable<TData2> datasource2)
{ if (dataSource1 == null || datasource2 == null || !dataSource1.Any() ||
!datasource2.Any()) throw new Exception("集合不為能空或者null"); foreach (TData1 data1
in dataSource1) { foreach (TData2 data2 in datasource2) { Add(data1, data2); }
} } }
我們再看測試類
public class UnitTest1 { public static MyDataprovider<int, int> myprovider =
new MyDataprovider<int, int>(new[] {3, 4, 5}, new[] {6, 7, 8}); [Theory]
[MemberData(nameof(UnitTest1.myprovider))] public void Test1(int x,int y) { int
result = x + y; Assert.Equal(x + y, result); } }
我們在new
MyDataprovider的時(shí)候通過構(gòu)造函數(shù)傳入兩個(gè)集合,MyDataprovider繼承了TheoryData的Add方法,把數(shù)據(jù)添加到theorydata中.
以上方法實(shí)際上生成了一個(gè)笛卡爾集{{3,6},{3,7},{3,8},{4,6},{4,7},{4,8},{5,6},{5,7},{5,8}}類似于Nunit里的values注解不加sequential,這個(gè)行為很多時(shí)候可能并不是我們想要的,我們想要的可能是{{3,6},{4,7},{5,8}}這樣的組合,這其實(shí)是可以在MyDataprovider里自定義的.
我們把MyDataprovider改為如下就可以了
public class MyDataprovider<TData1,TData2>:TheoryData<TData1,TData2> { public
MyDataprovider(IEnumerable<TData1> dataSource1,IEnumerable<TData2> datasource2)
{ if (dataSource1 == null || datasource2 == null || !dataSource1.Any() ||
!datasource2.Any()) throw new Exception("集合不為能空或者null"); var count1 =
dataSource1.Count(); var count2 = datasource2.Count(); if (count1 != count2)
throw new ArgumentException("兩個(gè)集合長度必須相等"); for (int i = 0; i < count1; i++) {
Add(dataSource1.ElementAt(i), datasource2.ElementAt(i)); } } }
這樣雖然可以把數(shù)據(jù)提供者轉(zhuǎn)移到外部了,然而去把簡單的問題搞的相當(dāng)復(fù)雜!
數(shù)據(jù)提供者之類數(shù)據(jù)提供者
前面介紹的數(shù)據(jù)提供者除了InlineData比較常用外,其它幾個(gè)都不是很實(shí)用,因?yàn)閿?shù)據(jù)和測試方法混合在一個(gè)類中,違反了職責(zé)單一的原則,最后一個(gè)看似比較好的解開了耦合,實(shí)際上卻帶來了更高的復(fù)雜度.這里介紹ClassDataAttribute,類數(shù)據(jù)提供者.
類數(shù)據(jù)提供者需要實(shí)現(xiàn)IEnumerable<Object[]>泛型接口,Xunit會(huì)自動(dòng)的調(diào)用其GetEnumerator方法來遍歷數(shù)據(jù)然后提供給測試類.
我們看以下數(shù)據(jù)提供類
public class MyDataClassProvider:IEnumerable<object[]> { public
IEnumerator<object[]> GetEnumerator() { yield return new object[] {3, 4}; yield
return new object[] {5, 9}; } IEnumerator IEnumerable.GetEnumerator() { return
GetEnumerator(); } }
以上類型的GetEnumerator繼承自接口,我們這里只提供了一些簡單數(shù)據(jù),當(dāng)然帶可以編寫更為復(fù)雜的數(shù)據(jù)提供邏輯,比如從數(shù)據(jù)庫里遍歷,然后轉(zhuǎn)化為可遍歷集合.
下面再看看它是如何被使用的.
[Theory] [ClassData(typeof(MyDataClassProvider))] public void Test1(int x,int
y) { var result = x + y; Assert.Equal(x + y, result); }
這里使用ClassData注解,傳入一個(gè)type類型.運(yùn)行的時(shí)候Xunit便可以給測試方法提供測試數(shù)據(jù)了
熱門工具 換一換
感谢您访问我们的网站,您可能还对以下资源感兴趣:
调教肉文小说-国产成本人片免费av-空姐av种子无码-在线观看免费午夜视频-综合久久精品激情-国产成人丝袜视频在线观看软件-大芭区三区四区无码-啊啊好爽啊啊插啊用力啊啊-wanch视频网-国产精品成人a免费观看