這篇文章給大家介紹.NET開(kāi)發(fā)中的單元測(cè)試工具NUnit怎么用,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
創(chuàng)新新互聯(lián),憑借十余年的網(wǎng)站設(shè)計(jì)制作、網(wǎng)站制作經(jīng)驗(yàn),本著真心·誠(chéng)心服務(wù)的企業(yè)理念服務(wù)于成都中小企業(yè)設(shè)計(jì)網(wǎng)站有超過(guò)千家案例。做網(wǎng)站建設(shè),選成都創(chuàng)新互聯(lián)。
NUnit是一個(gè)專門(mén)針對(duì)于.NET來(lái)寫(xiě)的單元測(cè)試框架,它是xUnit體系中的一員,在xUnit體系中還有針對(duì)Java的JUnit和針對(duì)C++的CPPUnit,在開(kāi)始的時(shí)候NUnit和xUnit體系中的大多數(shù)的做法一樣,僅僅是將Smalltalk或者Java版本轉(zhuǎn)換而來(lái),但是在.NET2.0之后它加入了一些特有的做法。NUnit的官方網(wǎng)站是:http://www.nunit.org/,目前的最新版本是:2.6.2。
NUnit的每個(gè)版本都提供了兩種形式的下載:安裝文件和免安裝方式,分別是*.msi格式和*.zip格式。前者需要安裝才能使用,并且會(huì)在安裝過(guò)程中創(chuàng)建一些快捷方式和注冊(cè)NUnit的dll到GAC,這樣以后編寫(xiě)NUnit測(cè)試類的時(shí)候添加NUnit的dll就像添加.Net Framework的dll一樣。如果是下載的zip格式的文件,則不會(huì)創(chuàng)建快捷方式和注冊(cè)dll,在編寫(xiě)單元測(cè)試類時(shí)需要手動(dòng)指定NUnit的dll的路徑。
NUnit的運(yùn)行有三種方式:命令行和圖形用戶界面。以周公當(dāng)前電腦上安裝的NUnit2.5.10為例,安裝路徑為:C:\Program Files (x86)\NUnit 2.5.10,其下有三個(gè)目錄:bin、doc和samples。在doc目錄下是軟件的文檔(英文),在samples目錄下則是一些樣例代碼。如果是采用免安裝模式的話,運(yùn)行NUnit就需要運(yùn)行bin目錄下的文件,在bin目錄下有net-1.1和net-2.0兩個(gè)文件夾,分別對(duì)應(yīng).net的不同版本。
下面介紹如何以不同的方式啟動(dòng)NUnit:
命令行模式:運(yùn)行nunit-console.exe。
圖形用戶界面模式:運(yùn)行nunit.exe。
并行(parallel)模式:運(yùn)行pnunit-launcher.exe。
注意:.Net2.0版本的NUnit是使用/platform:anycpu參數(shù)來(lái)編譯的,我們知道這樣的結(jié)果是運(yùn)行在x86的系統(tǒng)上會(huì)被JIT編譯成32位的程序,而在x64的系統(tǒng)上會(huì)被JIT編譯成64位的程序。如果使用NUnit在x64系統(tǒng)上測(cè)試32位的程序就會(huì)帶來(lái)問(wèn)題。為了避免這個(gè)問(wèn)題,可以使用nunit-agent-x86.exe/nunit-x86.exe來(lái)測(cè)試,因?yàn)樵诰幾g的時(shí)候使用了/platform:x86作為編譯參數(shù)。
下圖是運(yùn)行NUnit的GUI界面:
這些都是可以用來(lái)作為類或者方法的屬性,它們都是System.Attribute類的直接或間接子類,有如下:
Category:用來(lái)將測(cè)試分類。這個(gè)在主界面可以看到Tests/Categories兩個(gè)選項(xiàng)卡,如果給方法標(biāo)記了Category屬性就會(huì)在Categories選項(xiàng)卡中看得到。
Combinatorial:用來(lái)將來(lái)測(cè)試時(shí)需要測(cè)試各種可能的組合,比如如下代碼:
[Test, Combinatorial]
public void MyTest(
[Values(1, 2, 3)] int x,
[Values("A", "B")] string s)
{
string value = x + s;
Assert.Greater(2, value.Length);
}
測(cè)試時(shí)實(shí)際會(huì)測(cè)試6種情況:MyTest(1, "A")/MyTest(1, "B")/MyTest(2, "A")/MyTest(2, "B")/MyTest(3, "A")/MyTest(3, "B")。
Culture:設(shè)置測(cè)試時(shí)的語(yǔ)言環(huán)境,這對(duì)我們測(cè)試一些語(yǔ)言敏感的場(chǎng)景下有用,比如DateTime.ToString()在不同語(yǔ)言環(huán)境下得到的字符串并不相同。
Description:用于指定測(cè)試對(duì)應(yīng)的描述,如果選擇將測(cè)試結(jié)果生成XML文件,那么就會(huì)在XML文件中看到這些描述。
ExpectedException:指出執(zhí)行測(cè)試時(shí)將會(huì)拋出Exception。
Explicit:如果測(cè)試的類或者方法使用此Attribute,那么在使用帶GUI的NUnit測(cè)試時(shí)這個(gè)類或者方法必須在界面上選定才會(huì)被執(zhí)行。
Explicit:忽略某個(gè)測(cè)試類或者方法。
Maxtime:測(cè)試方法最大執(zhí)行的毫秒數(shù),如果程序的執(zhí)行時(shí)間超過(guò)指定數(shù)值,那么就會(huì)被認(rèn)為測(cè)試失敗。
Random:用于指定如何隨機(jī)生成參數(shù)來(lái)測(cè)試方法。如下面的代碼:
[Test]
public void TestDemo1(
[Values(1, 2, 3)] int x,
[Random(-10,10,2)] int y)
{
Assert.Greater(x + y, 0);
}
表示方法TestDemo1會(huì)生成6個(gè)測(cè)試,1,2,3分別作為參數(shù)x的值與兩次從-10到10之間的隨機(jī)數(shù)y組成6次測(cè)試。
Range:指定參數(shù)的方法,如下面的方法:
[Test]
public void TestDemo2(
[Range(0, 11, 4)] int x)
{
Assert.AreEqual(x%3,0);
}
表示從0開(kāi)始遞增,步長(zhǎng)為4,且不大于11。
Repeat:將重復(fù)測(cè)試的次數(shù)。
RequiresMTA:表示測(cè)試時(shí)需要多線程單元(multi-threaded apartment)。
RequiresSTA:表示測(cè)試時(shí)需要單線程單元(single-threaded apartment)。
SetUp:在每個(gè)測(cè)試方法開(kāi)始之前執(zhí)行的初始化操作。在NUnit 2.5之前要求每個(gè)類只能有一個(gè)帶SetUp屬性的實(shí)例方法,但在NUnit 2.5之后則沒(méi)有次數(shù)和必須是實(shí)例方法的限制。
TearDown:與SetUp的作用相反,是在每個(gè)測(cè)試方法執(zhí)行結(jié)束之后執(zhí)行的方法。在NUnit 2.5之前要求每個(gè)類只能有一個(gè)帶SetUp屬性的實(shí)例方法,但在NUnit 2.5之后則沒(méi)有次數(shù)和必須是實(shí)例方法的限制。
Test:用來(lái)標(biāo)記需要測(cè)試的方法,在NUnit 2.5之前只能用于標(biāo)記實(shí)例方法,在NUnit 2.5之后則可以用于標(biāo)記靜態(tài)方法。
TestCase:標(biāo)記方法具有參數(shù)并且提供了在測(cè)試時(shí)需要的參數(shù)。如下面的代碼:
[TestCase(12, 3, 4)]
[TestCase(12, 2, 6)]
[TestCase(12, 4, 3)]
public void DivideTest(int n, int d, int q)
{
Assert.AreEqual(q, n / d);
}
將會(huì)執(zhí)行三次測(cè)試,相當(dāng)于:
[Test]
public void DivideTest()
{
Assert.AreEqual(4,12/3);
}
[Test]
public void DivideTest()
{
Assert.AreEqual(6,12/2);
}
[Test]
public void DivideTest()
{
Assert.AreEqual(3,12/4);
}
TestFixture:標(biāo)記一個(gè)類可能具有[Test]/[SetUp]/[TearDown]方法,但這個(gè)類不能是抽象類。
TestFixtureSetUp:標(biāo)記在類中所有測(cè)試方法執(zhí)行之前執(zhí)行的方法。在NUnit 2.5之前只能在類中將此標(biāo)記最多使用于一個(gè)實(shí)例方法,在NUnit 2.5之后則可以標(biāo)記多個(gè)方法,而且不限于實(shí)例方法還可以用于靜態(tài)方法。
TestFixtureTearDown:標(biāo)記在類中所有測(cè)試方法執(zhí)行之后再執(zhí)行的方法。在NUnit 2.5之前只能在類中將此標(biāo)記最多使用于一個(gè)實(shí)例方法,在NUnit 2.5之后則可以標(biāo)記多個(gè)方法,而且不限于實(shí)例方法還可以用于靜態(tài)方法。
Timeout:標(biāo)記被測(cè)試的方法最大的執(zhí)行時(shí)間,如果超出標(biāo)記的時(shí)間,則會(huì)被取消執(zhí)行并且被標(biāo)記為測(cè)試失敗。
Values:標(biāo)記作為測(cè)試方法的一系列的參數(shù)。前面的代碼實(shí)例中就有用法實(shí)例。
斷言是所有基于xUnit單元測(cè)試系列的核心,NUnit通過(guò)NUnit.Framework.Assert類提供了豐富的斷言。具體說(shuō)來(lái),NUnit總共提供了11個(gè)類別的斷言,它們是:
Equality Asserts:用于斷言對(duì)象是否相等方面的斷言,主要表現(xiàn)為兩個(gè)方法的重載:Assert.AreEqual()和Assert.AreNotEqual()兩種形式的重載,重載參數(shù)包括了常見(jiàn)的基本數(shù)值類型(int/float/double等)和引用類型(表現(xiàn)為使用object作為參數(shù)).
Identity Asserts:用于判斷引用類型的對(duì)象是否是同一個(gè)引用的斷言及斷言對(duì)象是否存在于某個(gè)集合中,如Assert.AreSame、Assert.AreNotSame及Assert.Contains。
Condition Asserts:用于某些條件的斷言,如:Assert.IsTrue、Assert.True、Assert.IsFalse、Assert.False、Assert.IsNull、Assert.Null、Assert.IsNotNull、Assert.NotNull、Assert.IsNaN、Assert.IsEmpty及Assert.IsNotEmpty。
Comparisons Asserts:用于數(shù)值及實(shí)現(xiàn)了IComparable接口的類型之間的斷言,如Assert.Greater(大于)、Assert.GreaterOrEqual(大于或等于)、Assert.Less(小于)、Assert.LessOrEqual(小于或等于)。
Type Asserts:用于類型之間的判斷,比如判斷某個(gè)實(shí)例是否是某一類型或者是從某個(gè)類型繼承,如:Assert.IsInstanceOfType、Assert.IsNotInstanceOfType、Assert.IsAssignableFrom、Assert.IsNotAssignableFrom。在NUnit 2.5之后就增加了泛型方法,如Assert.IsInstanceOf<T>、Assert.IsNotInstanceOf<T>、Assert.IsAssignableFrom<T>、Assert.IsNotAssignableFrom<T>。。
Exception Asserts:有關(guān)異常方面的斷言,如Assert.Throws/Assert.Throws<T>、Assert.DoesNotThrow、Assert.Catch/Assert.Catch<T>。
Utility Methods:用于精確控制測(cè)試過(guò)程,總共有四個(gè)方法,分別是:Assert.Pass、Assert.Fail、Assert.Ignore、Assert.Inconclusive。Assert.Pass和Assert.Fail是相反的,前者是表示將立即終止測(cè)試并將測(cè)試結(jié)果標(biāo)識(shí)為成功通過(guò)測(cè)試,后者是立即終止測(cè)試并將測(cè)試結(jié)果標(biāo)識(shí)為測(cè)試失敗。Assert.Ignore表示忽略測(cè)試,這個(gè)標(biāo)記可以用于標(biāo)識(shí)測(cè)試方法或者測(cè)試的類。
StringAssert:用于字符串方面的斷言,提供的方法有StringAssert.Contains、StringAssert.StartsWith、StringAssert.EndsWith、StringAssert.AreEqualIgnoringCase及StringAssert.IsMatch。
CollectionAssert:關(guān)于集合方面的斷言,提供的方法有CollectionAssert.AllItemsAreInstancesOfType、CollectionAssert.AllItemsAreNotNull、CollectionAssert.AllItemsAreUnique、CollectionAssert.AreEqual、CollectionAssert.AreEquivalent、CollectionAssert.AreNotEqual、CollectionAssert.AreNotEquivalent、CollectionAssert.Contains、CollectionAssert.DoesNotContain、CollectionAssert.IsSubsetOf、CollectionAssert.IsNotSubsetOf、CollectionAssert.IsEmpty、CollectionAssert.IsNotEmpty和CollectionAssert.IsOrdered。
FileAssert:用于文件相關(guān)的斷言,主要提供兩個(gè)方法:FileAssert.AreEqual和FileAssert.AreNotEqual。
DirectoryAssert:用于文件夾的斷言,提供的方法有:DirectoryAssert.AreEqual、DirectoryAssert.AreNotEqual、DirectoryAssert.IsEmpty、DirectoryAssert.IsNotEmpty、DirectoryAssert.IsWithin和DirectoryAssert.IsNotWithin。
第一次打開(kāi)NUnit時(shí)會(huì)是一個(gè)空白界面,如下圖所示:
首先我們需要?jiǎng)?chuàng)建一個(gè)NUnit項(xiàng)目,點(diǎn)擊[File]->[New Project]會(huì)彈出一個(gè)保存NUnit項(xiàng)目的對(duì)話框,選擇合適的路徑并輸入合適的名稱(注意文件后綴名為.nunit),然后點(diǎn)擊保存按鈕,這樣就創(chuàng)建了一個(gè)NUnit測(cè)試項(xiàng)目。以后我們就可以再次打開(kāi)這個(gè)項(xiàng)目了。
此時(shí)這個(gè)NUnit項(xiàng)目中還不包含任何單元測(cè)試用例,我們需要?jiǎng)?chuàng)建包含測(cè)試用例的項(xiàng)目。打開(kāi)Visual Studio創(chuàng)建一個(gè)類庫(kù)項(xiàng)目(在真實(shí)項(xiàng)目中通常做法是向當(dāng)前解決方案中添加類庫(kù)項(xiàng)目,這樣便于解決dll引用問(wèn)題),接著我們需要添加NUnit的引用,這取決于我們是采用安裝方式還是免安裝方式,通常情況下我們只需要添加對(duì)nunit.framework(對(duì)應(yīng)的dll是unit.framework.dll)的引用就夠了。
這里周公采用的示例代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using NUnit.Framework; namespace UnitTestDemo { [TestFixture] public class NUnitTestDemo { private IList<int> intList = new List<int>(); [SetUp] [Category("NA")] public void BeforeTest() { Console.WriteLine("BeforeTest"); } [TestFixtureSetUp] [Category("NA")] public void BeforeAllTests() { Console.WriteLine("BeforeAllTests"); } [TearDown] [Category("NA")] public void AfterTest() { Console.WriteLine("AfterTest"); } [TestFixtureTearDown] [Category("NA")] public void AfterAllTests() { Console.WriteLine("AfterAllTests"); } [Test] [Category("NA")] public void Test1() { Console.WriteLine("Test1"); } [Test] [Category("NA")] public void Test2() { Console.WriteLine("Test2"); } [Test] public void TestFloat() { float value = 0.9999999999999999999999999999f; //value = 0.9999999999999999999999999999; Console.WriteLine("float value:" + value); Assert.AreEqual(value, 1f); Console.WriteLine("TestFloat"); } [Test] public void TestDouble() { double value = 0.9999999999999999999999999999d; Console.WriteLine("double value:" + value); Assert.AreEqual(value, 1d); Console.WriteLine("Test2"); } [Test] public void TestDecimal() { decimal value = 0.9999999999999999999999999999M; Console.WriteLine("decimal value:" + value); Assert.AreEqual(value, 1M); Console.WriteLine("Test2"); } [Test,Repeat(3)] public void TestIntList2() { Assert.AreEqual(0, intList.Count); } [Test] public void TestIntList1() { intList.Add(1); Assert.AreEqual(1, intList.Count); } [TestCase(12, 3, 4)] [TestCase(12, 2, 6)] [TestCase(12, 4, 3)] public void DivideTest(int n, int d, int q) { Assert.AreEqual(q, n / d); } [Test, Combinatorial,Description("This is used for show Combinatorial")] public void MyTest( [Values(1, 2, 3)] int x, [Values("A", "B")] string s) { string value = x + s; Assert.Greater(2, value.Length); } [Test] public void TestDemo1( [Values(1, 2, 3)] int x, [Random(-10,10,2)] int y) { Assert.Greater(x + y, 0); } [Test] public void TestDemo2( [Range(0, 11, 4)] int x) { Assert.AreEqual(x%3,0); } } }
編譯項(xiàng)目生成dll。我們就可以在NUnit主界面上點(diǎn)擊[Project]->[Add Assembly...]來(lái)添加剛才編譯生成的dll,加載成功后界面如下所示:
點(diǎn)擊界面上的[Run]按鈕就可以開(kāi)始測(cè)試了。注意這種方式下是測(cè)試所有的測(cè)試方法,如果我們只想測(cè)試某幾個(gè)方法,可以勾選方面前面的復(fù)選框(默認(rèn)情況下復(fù)選框不出現(xiàn),需要按照點(diǎn)擊[Tools]->[Setting]打開(kāi)設(shè)置界面,然后點(diǎn)擊在[GUI]下面找到[Tree Display],勾選上“Show CheckBoxes”即可)。
如果我們只是想單獨(dú)測(cè)試某個(gè)方法,那就更簡(jiǎn)單了——直接雙擊那個(gè)測(cè)試方法即可。
有時(shí)候我們進(jìn)行測(cè)試時(shí)還會(huì)用到一些config文件里面的配置信息,如在app.config/web.config中保存數(shù)據(jù)庫(kù)連接字符串信息及其他的配置信息,為了能讓NUnit測(cè)試時(shí)能讀取app.config/web.config中保存的配置信息,我們需要對(duì)NUnit進(jìn)行配置。
為了演示,我們制定以下信息:
項(xiàng)目名稱:UnitTestDemo
項(xiàng)目位置:D:\BlogCode\UnitTestDemo\
項(xiàng)目編譯模式(Debug/Release):Debug
為了演示剛才的如何對(duì)config文件中保存的數(shù)據(jù)進(jìn)行測(cè)試,我們?cè)趧偛诺拇a基礎(chǔ)上編寫(xiě)了三個(gè)測(cè)試用例,代碼如下:
[Test] public void Test0_51CTOBlog() { StringAssert.AreEqualIgnoringCase(ConfigurationManager.AppSettings["51ctoBlog"], "http://zhoufoxcn.blog.51cto.com"); } [Test] public void Test0_CSDNBlog() { StringAssert.AreEqualIgnoringCase(ConfigurationManager.AppSettings["CSDNBlog"], "http://blog.csdn.net/zhoufoxcn"); } [Test] public void Test0_SinaWeiBo() { StringAssert.AreEqualIgnoringCase(ConfigurationManager.AppSettings["SinaWeiBo"], "http://weibo.com/zhoufoxcn"); }
同時(shí)在app.config文件的appSettings節(jié)點(diǎn)增加以下數(shù)據(jù):
<appSettings> <add key="51ctoBlog" value="http://zhoufoxcn.blog.51cto.com"/> <add key="CSDNBlog" value="http://blog.csdn.net/zhoufoxcn"/> <add key="SinaWeiBo" value="http://weibo.com/zhoufoxcn"/> </appSettings>
如果不在NUnit上做任何設(shè)置,我們會(huì)得到錯(cuò)誤的結(jié)果,如下圖所示:
這時(shí),我們可以按照如下步驟配置,點(diǎn)擊[Project]-[Edit...]打開(kāi)如下界面:
在上圖的界面中設(shè)置ApplicationBase為當(dāng)前要測(cè)試的dll所在的路徑,本例中為:D:\BlogCode\UnitTestDemo\bin\Debug(注意如果復(fù)制全路徑到文本框中NUnit會(huì)自動(dòng)更改為相對(duì)路徑),因?yàn)楫?dāng)前項(xiàng)目是名為UnitTestDemo的類庫(kù)項(xiàng)目,所以對(duì)應(yīng)config文件名稱為UnitTestDemo.dll.config,將其填入Configuration File Name后面的文本框中,然后我們?cè)俅吸c(diǎn)擊[Run]按鈕就會(huì)看到測(cè)試通過(guò)。
作為xUnit體系中的一員,NUnit確實(shí)給.Net開(kāi)發(fā)人員進(jìn)行單元測(cè)試帶來(lái)了不少方便,在早期我們一直都是使用NUnit進(jìn)行單元測(cè)試的。但是也存在著一些不足之處,比如:1.在xUnit體系中的JUnit是在測(cè)試每個(gè)方法時(shí)都是新生成一個(gè)實(shí)例,而在NUnit中確實(shí)一個(gè)TestFixture只會(huì)生成一個(gè)實(shí)例,這樣一來(lái)如果對(duì)要包含單元測(cè)試類中的實(shí)例數(shù)據(jù)進(jìn)行更改會(huì)可能會(huì)影響到其它的測(cè)試方法(像JUnit那樣每次都生成一個(gè)實(shí)例則不會(huì)產(chǎn)生這種情況)。2.早期大多數(shù)人以為像JUnit中一樣,[SetUp]、[TearDown]只會(huì)在所有測(cè)試前、后分別執(zhí)行一次,實(shí)際情況是在每個(gè)測(cè)試前、后都會(huì)執(zhí)行一次,為了達(dá)到JUnit中[SetUp]、[TearDown]這樣的效果,只能新增TestFixtureSetUp、TestFixtureTearDown屬性。除此之外,還存在一些缺點(diǎn)和不足。
關(guān)于.NET開(kāi)發(fā)中的單元測(cè)試工具NUnit怎么用就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
新聞名稱:.NET開(kāi)發(fā)中的單元測(cè)試工具NUnit怎么用
瀏覽地址:http://m.newbst.com/article18/jeehgp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、定制網(wǎng)站、標(biāo)簽優(yōu)化、建站公司、微信公眾號(hào)、手機(jī)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)