• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Life is Good.

            Enhance Tech and English
            隨筆 - 65, 文章 - 20, 評(píng)論 - 21, 引用 - 0
            數(shù)據(jù)加載中……

            NUnit詳細(xì)使用方法

            現(xiàn)在做的項(xiàng)目要用到NUnit 去做TDD開(kāi)發(fā),轉(zhuǎn)帖一篇很詳細(xì)的文章, 以后再加上怎么去創(chuàng)建一個(gè)UNnit Test project.

            http://www.cnblogs.com/confach/archive/2005/06/20/177817.html
            前一段時(shí)間,有人問(wèn)我在.NET里如何進(jìn)行TDD開(kāi)發(fā).這個(gè)問(wèn)題促使我想對(duì)NUnit做一個(gè)詳細(xì)的介紹.因?yàn)槲覀兇蠹叶贾繬Unit是在.NET進(jìn)行TDD的利器.
            如果你已經(jīng)知道很多關(guān)于NUnit的應(yīng)用,請(qǐng)指出我的不對(duì)之處和提出一些建議,使本文更加完善.如果你對(duì)NUnit還不是很了解的話(huà),我建議你還是閱讀一下.
            本文分為以下部分:

            1. TDD的簡(jiǎn)介

            首先什么是TDD呢?Kent Beck在他的<<測(cè)試驅(qū)動(dòng)開(kāi)發(fā) >>(Addison-Wesley Professional,2003)一書(shū)中,使用下面2個(gè)原則來(lái)定義TDD:
            ·除非你有一個(gè)失敗的自動(dòng)測(cè)試,永遠(yuǎn)不要寫(xiě)一單行代碼.
            ·阻止重復(fù)
            我想第一個(gè)原則是顯而易見(jiàn)的.在沒(méi)有失敗的自動(dòng)測(cè)試下就不要寫(xiě)代碼.因?yàn)闇y(cè)試是嵌入在代碼必須滿(mǎn)足的需求中.如果沒(méi)有需求,就沒(méi)有必要實(shí)現(xiàn)任何東西.所以這個(gè)原則阻止我們?nèi)?shí)現(xiàn)那些沒(méi)有測(cè)試和在解決方案中不需要的功能.
            第二個(gè)原則說(shuō)明了在一個(gè)程序中,不應(yīng)該包含重復(fù)的代碼.如果代碼重復(fù),我想這就是不好的軟件設(shè)計(jì)的象征.隨著時(shí)間的流逝,它會(huì)對(duì)程序造成不一致的問(wèn)題,并且使代碼變非常混亂 ,因?yàn)槲覀儠r(shí)常不會(huì)記得重復(fù)代碼的位置.如果發(fā)現(xiàn)代碼重復(fù),我想我們應(yīng)該立即刪除代碼重復(fù).其實(shí)這就涉及到重構(gòu)了.在這里我就不多講了.
            一般來(lái)說(shuō),測(cè)試分為2種類(lèi)型,一是程序員自己的測(cè)試,另外一種是客戶(hù)的測(cè)試.關(guān)于客戶(hù)測(cè)試,我推薦一個(gè)FIT的框架,非常不錯(cuò)。在這里,我們講的TDD就是程序員測(cè)試.那么什么是程序員測(cè)試呢?我認(rèn)為就是我們常說(shuō)的單元測(cè)試.既然是單元測(cè)試,在.NET里勢(shì)必會(huì)用到某些工具,目前最著名恐怕就是我即將介紹的NUnit了,

            2.NUnit的介紹

            NUnit是一個(gè)單元測(cè)試框架,專(zhuān)門(mén)針對(duì)于.NET來(lái)寫(xiě)的.其實(shí)在前面有JUnit(Java),CPPUnit(C++),他們都是xUnit的一員.最初,它是從JUnit而來(lái).現(xiàn)在的版本是2.2.接下來(lái)我所用的都是基于這個(gè)版本.
            NUnit最初是由James W. Newkirk, Alexei A. Vorontsov 和Philip A. Craig, 后來(lái)開(kāi)發(fā)團(tuán)隊(duì)逐漸龐大起來(lái).在開(kāi)發(fā)過(guò)程中, Kent Beck 和Erich Gamma2位牛人也提供了許多幫助.看來(lái)對(duì)于NUnit還真是下了一番力氣了.J
            NUnit是xUnit家族種的第4個(gè)主打產(chǎn)品,完全由C#語(yǔ)言來(lái)編寫(xiě),并且編寫(xiě)時(shí)充分利用了許多.NET的特性,比如反射,客戶(hù)屬性等等.
            最重要的一點(diǎn)是它適合于所有.NET語(yǔ)言.
            如果你還沒(méi)有下載,可以到http://www.nunit.org/去下載.

            2.1 NUnit的介紹

               Ok,下面正式講解NUnit.在講解之前,看看幾張圖片:
                 
            圖1  NUnit運(yùn)行的效果

                                 圖2   NUnit運(yùn)行的另外一個(gè)效果
             從中我們可以非常容易發(fā)現(xiàn),右邊是個(gè)狀態(tài)條,圖1是紅色的,圖2是綠色的.為什么會(huì)這樣呢?因?yàn)槿绻袦y(cè)試案例運(yùn)行成功,就為綠色,反之如果有一個(gè)不成功,則為紅色,但也有黃色的.左面的工作域內(nèi)則是我們寫(xiě)的每一個(gè)單元測(cè)試.
            通過(guò)上面的圖片,我想你對(duì)NUnit有個(gè)總的了解了.
            接下來(lái)還是分為2個(gè)部分,一是NUnit的布局,另外一部分就是它的核心概念.
            首先熟悉一下NUnit GUI的布局.
            讓我們更進(jìn)一步看一下測(cè)試運(yùn)行器窗口的布局。在右邊面板的中間,可以看到測(cè)試進(jìn)度條。進(jìn)度條的顏色反映了測(cè)試執(zhí)行的狀態(tài):
            • 綠色 描述目前所執(zhí)行的測(cè)試都通過(guò)
            • 黃色 意味某些測(cè)試忽略,但是這里沒(méi)有失敗
            • 紅色 表示有失敗
            底部的狀態(tài)條表示下面的狀態(tài):
            • 狀態(tài).說(shuō)明了現(xiàn)在運(yùn)行測(cè)試的狀態(tài)。當(dāng)所有測(cè)試完成時(shí),狀態(tài)變?yōu)?em>Completed.運(yùn)行測(cè)試中,狀態(tài)是Running: <test-name> (<test-name>是正在運(yùn)行的測(cè)試名稱(chēng))。
            • Test Cases說(shuō)明加載的程序集中測(cè)試案例的總個(gè)數(shù)。這也是測(cè)試樹(shù)里葉子節(jié)點(diǎn)的個(gè)數(shù)。
            • Tests Run 已經(jīng)完成的測(cè)試個(gè)數(shù)。
            • Failures  到目前為止,所有測(cè)試中失敗的個(gè)數(shù).
            • Time  顯示運(yùn)行測(cè)試時(shí)間(以秒計(jì))
            File主菜單有以下內(nèi)容:
            • New Project允許你創(chuàng)建一個(gè)新工程。工程是一個(gè)測(cè)試程序集的集合。這種機(jī)制讓你組織多個(gè)測(cè)試程序集,并把他們作為一個(gè)組對(duì)待。
            • Open 加載一個(gè)新的測(cè)試程序集,或一個(gè)以前保存的NUnit工程文件。
            • Close關(guān)閉現(xiàn)在加載的測(cè)試程序集或現(xiàn)在加載的NUnit工程。
            • Save 保存現(xiàn)在的Nunit工程到一個(gè)文件。如果正工作單個(gè)程序集,本菜單項(xiàng)允許你創(chuàng)建一個(gè)新的NUnit工程,并把它保存在文件里。
            • Save As允許你將現(xiàn)有NUnit工程作為一個(gè)文件保存。
            • Reload 強(qiáng)制重載現(xiàn)有測(cè)試程序集或NUnit工程。NUnit-Gui自動(dòng)監(jiān)測(cè)現(xiàn)加載的測(cè)試程序集的變化。
            當(dāng)程序集變化時(shí),測(cè)試運(yùn)行器重新加載測(cè)試程序集。(當(dāng)測(cè)試正運(yùn)行時(shí),現(xiàn)在加載的測(cè)試程序集不會(huì)重新加載。在測(cè)試運(yùn)行之間測(cè)試程序集僅可以重新加載。一個(gè)忠告:如果測(cè)試程序集依賴(lài)另外一個(gè)程序集,測(cè)試運(yùn)行器不會(huì)觀察任何依賴(lài)的程序集。對(duì)測(cè)試運(yùn)行器來(lái)說(shuō),強(qiáng)制一個(gè)重載使全部依賴(lài)的程序集變化可見(jiàn)。
            • Recent Files  說(shuō)明5個(gè)最近在NUnit中加載的測(cè)試程序集或NUnit工程(這個(gè)列表在Windows注冊(cè)表,由每個(gè)用戶(hù)維護(hù),因此如果你共享你的PC,你僅看到你的測(cè)試)。最近程序集的數(shù)量可以使用Options菜單項(xiàng)修改,可以訪(fǎng)問(wèn)Tool主菜單。
            • Exit退出。
            •  View菜單有以下內(nèi)容:
            • Expand一層層擴(kuò)展現(xiàn)在樹(shù)中所選節(jié)點(diǎn)
            • Collapse 折疊現(xiàn)在樹(shù)中選擇的節(jié)點(diǎn)
            • Expand All遞歸擴(kuò)展樹(shù)中所選節(jié)點(diǎn)后的所有節(jié)點(diǎn)
            • Collapse All遞歸折疊樹(shù)中所選節(jié)點(diǎn)后的所有節(jié)點(diǎn)
            • Expand Fixtures擴(kuò)展樹(shù)中所有代表測(cè)試fixture的節(jié)點(diǎn)。
            • Collapse Fixtures 折疊樹(shù)中所有代表測(cè)試fixture的節(jié)點(diǎn)。
            • Properties 顯示樹(shù)中現(xiàn)所選節(jié)點(diǎn)的屬性。
            • Tools 菜單由這些項(xiàng):
            • Save Results as XML作為一XML文件保存運(yùn)行測(cè)試的結(jié)果。
            • Options讓你定制NUnit的行為。
            現(xiàn)在看看右邊,你已經(jīng)熟悉Run按鈕和進(jìn)度條。這里還有一個(gè)緊跟Run按鈕的Stop按鈕:點(diǎn)擊這個(gè)按鈕會(huì)終止執(zhí)行正運(yùn)行的測(cè)試。進(jìn)度條下面是一個(gè)文本窗口,在它上方,由以下4個(gè)標(biāo)簽:
            • Errors and Failures 窗口顯示失敗的測(cè)試。在我們的例子里,這個(gè)窗口是空。
            • Tests Not Run 窗口顯示沒(méi)有得到執(zhí)行的測(cè)試。
            • Console.Error 窗口顯示運(yùn)行測(cè)試產(chǎn)生的錯(cuò)誤消息。這些此消息是應(yīng)用程序代碼使用Console.Error輸出流可以輸出的。
            • Console.Out窗口顯示運(yùn)行測(cè)試打印到Console.Error輸出流的文本消息。

            2.2 一些常用屬性

             接下來(lái),我將講述這個(gè)框架如何使用.同時(shí)也涉及到一些非常重要的概念,我想其客戶(hù)屬性是非常重要的.在NUnit里,有以下幾種屬性:
            • Test Fixture
            • Test
            下面我將對(duì)每種屬性一一講解.

            TestFixtureAttribute

                本屬性標(biāo)記一個(gè)類(lèi)包含測(cè)試,當(dāng)然setup和teardown方法可有可無(wú).(關(guān)于setup 和teardown方法在后面介紹)
                做為一個(gè)測(cè)試的類(lèi),這個(gè)類(lèi)還有一些限制
            • 必須是Public,否則NUnit看不到它的存在.
            • 它必須有一個(gè)缺省的構(gòu)造函數(shù),否則是NUnit不會(huì)構(gòu)造它.
            • 構(gòu)造函數(shù)應(yīng)該沒(méi)有任何副作用,因?yàn)镹Unit在運(yùn)行時(shí)經(jīng)常會(huì)構(gòu)造這個(gè)類(lèi)多次,如果要是構(gòu)造函數(shù)要什么副作用的話(huà),那不是亂了.
            舉個(gè)例子
             1  using System;
             2  using NUnit.Framework;
             3  namespace MyTest.Tests
             4{
             5
             6  [TestFixture]
             7  public class PriceFixture
             8  {
             9    // 
            10  }

            11}

            12

            TestAttribute

             Test屬性用來(lái)標(biāo)記一個(gè)類(lèi)(已經(jīng)標(biāo)記為T(mén)estFixture)的某個(gè)方法是可以測(cè)試的.為了和先前的版本向后兼容,頭4個(gè)字符(“test”)忽略大小寫(xiě).(參看http://nunit.org/test.html)
            這個(gè)測(cè)試方法可以定義為:       
            public void MethodName()
            從上面可以看出,這個(gè)方法沒(méi)有任何參數(shù),其實(shí)測(cè)試方法必須沒(méi)有參數(shù).如果我們定義方法不對(duì)的話(huà),這個(gè)方法不會(huì)出現(xiàn)在測(cè)試方法列表中.也就是說(shuō)在NUnit的界面左邊的工作域內(nèi),看不到這個(gè)方法.還有一點(diǎn)就是這個(gè)方法不返回任何參數(shù),并且必須為Public.
            例如:
             1using System;
             2using NUnit.Framework;
             3
             4namespace MyTest.Tests
             5{
             6  [TestFixture]
             7  public class SuccessTests
             8  {
             9    [Test] public void Test1()
            10    /*  */ }
            11  }

            12}

            13
            14
            一般來(lái)說(shuō),有了上面兩個(gè)屬性,你可以做基本的事情了.
            
            另外,我們?cè)賹?duì)如何進(jìn)行比較做一個(gè)描述。 在NUnit中,用Assert(斷言)進(jìn)行比較,Assert是一個(gè)類(lèi),它包括以下方法:AreEqual,AreSame,Equals, Fail,Ignore,IsFalse,IsNotNull,具體請(qǐng)參看NUnit的文檔。

            3.如何在.NET中應(yīng)用NUnit

            我將舉個(gè)例子,一步一步演示如何去使用NUnit.

            第1步.為測(cè)試代碼創(chuàng)建一個(gè)Visual Studio工程。

            在Microsoft Visual Studio .NET中,讓我們開(kāi)始創(chuàng)建一個(gè)新的工程。選擇Visual C#工程作為工程類(lèi)型,Class Library作為模板。將工程命名為NUnitQuickStart.圖4-1是一個(gè)描述本步驟的Visual Studio .NET。
             
                                        圖 4-1: 創(chuàng)建第一個(gè)NUnit工程

            第2步.增加一個(gè)NUnit框架引用

            在Microsoft Visual Studio .NET里創(chuàng)建這個(gè)例子時(shí),你需要增加一個(gè)NUnit.framework.dll引用,如下:
            在Solution Explorer右擊引用,然后選擇增加引用
               NUnit.framework組件,在Add Reference對(duì)話(huà)框中按Select和OK按鈕。
            圖4-2 描述了這步:
             
            圖 4-2: 增加一個(gè) NUnit.framework.dll 引用到工程

            第3步.為工程加一個(gè)類(lèi).

            為工程加一個(gè)NumbersFixture類(lèi)。這里是這個(gè)例子的代碼。
             1using System; 
             2using NUnit.Framework; 
             3  
             4namespace NUnitQuickStart 
             5
             6            [TestFixture] 
             7            public class NumersFixture 
             8            
             9                        [Test] 
            10                        public void AddTwoNumbers() 
            11                        
            12                                    int a=1
            13                                    int b=2
            14                                    int sum=a+b; 
            15                                    Assert.AreEqual(sum,3); 
            16                        }
             
            17            }
             
            18}

            19

            第4步.建立你的Visual Studio 工程,使用NUnit-Gui測(cè)試

            從程序->NUnit2.2打開(kāi)NUnit-gui,加載本本工程編譯的程序集.
            為了在Visual Studio .NET中自動(dòng)運(yùn)行NUnit-Gui,你需要建立NUnit-Gui作為你的啟動(dòng)程序:
            在 Solution Explorer里右擊你的NunitQuickStart工程。
            在彈出菜單中選擇屬性。
            在顯示的對(duì)話(huà)框的左面,點(diǎn)擊Configuration Properties夾
            選擇出現(xiàn)在Configuration Properties夾下的Debugging。
            在屬性框右邊的Start Action部分,選擇下拉框的Program作為Debug Mode值。
            按Apply按鈕
            設(shè)置NUnit-gui.exe 作為Start Application。,你既可以鍵入nunit-gui.exe的全路徑,也可使用瀏覽按鈕來(lái)指向它。
            圖4-3 幫助描述本步驟:
              
            圖 4-3:將NUnit-Gui 作為工程的測(cè)試運(yùn)行器

            第5步.編譯運(yùn)行測(cè)試.

             現(xiàn)在編譯solution。成功編譯后,開(kāi)始應(yīng)用程序。NUnit-Gui測(cè)試運(yùn)行器出現(xiàn)。當(dāng)你第一次開(kāi)始NUnit-Gui,它打開(kāi)時(shí)沒(méi)有測(cè)試加載。從File菜單選擇Oprn,瀏覽NUnitQuickStart.dll的路徑。當(dāng)你加載了測(cè)試的程序集,測(cè)試運(yùn)行器為加載的程序集的測(cè)試產(chǎn)生一個(gè)可見(jiàn)的表現(xiàn)。在例子中,測(cè)試程序集僅有一個(gè)測(cè)試,測(cè)試程序集的結(jié)構(gòu)如圖4-4所示:
             
             圖 4-4: 測(cè)試程序集的測(cè)試在 NUnit-Gui中的視圖
            按Run按鈕。樹(shù)的節(jié)點(diǎn)變?yōu)榫G色,而且測(cè)試運(yùn)行器窗口上的進(jìn)度條變綠,綠色代表成功通過(guò)。
             

            4.其他的一些核心概念

             上面的例子介紹了基本的NUnit特性和功能. TestFixture, Test, 和 Assert是3個(gè)最基本的特征,我們可以用這些特性進(jìn)行程序員測(cè)試了.但是有的時(shí)候,你覺(jué)得這3個(gè)遠(yuǎn)遠(yuǎn)不夠,比如有的時(shí)候打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接多次,有沒(méi)有只讓它打開(kāi)一次的方法呢?如果我想把測(cè)試分類(lèi),應(yīng)該怎樣實(shí)現(xiàn)呢?如果我想忽略某些測(cè)試,又應(yīng)該如何去完成呢?不用擔(dān)心,NUnit已經(jīng)有這樣的功能了.
            下面我們一一作出回答.

            SetUp/TearDown 屬性

            在早期給的test fixture定義里,我們說(shuō)test fixture的測(cè)試是一組常規(guī)運(yùn)行時(shí)資源.在測(cè)試完成之后,或是在測(cè)試執(zhí)行種,或是釋放或清除之前,這些常規(guī)運(yùn)行時(shí)資源在一確定的方式上可能需要獲取和初始化.NUnit使用2個(gè)額外的屬性:SetUpTearDown,就支持這種常規(guī)的初始化/清除.我們上面的例子來(lái)描述這個(gè)功能.讓我們?cè)黾映朔?
             1using System; 
             2using NUnit.Framework; 
             3  
             4namespace NUnitQuickStart 
             5
             6            [TestFixture] 
             7            public class NumersFixture 
             8            
             9                        [Test] 
            10                        public void AddTwoNumbers() 
            11                        
            12                                    int a=1
            13                                    int b=2
            14                                    int sum=a+b; 
            15                                    Assert.AreEqual(sum,3); 
            16                        }
             
            17                        [Test] 
            18                        public void MultiplyTwoNumbers() 
            19                        
            20                                    int a = 1
            21                                    int b = 2
            22                                    int product = a * b; 
            23                                    Assert.AreEqual(2, product); 
            24                        }
             
            25  
            26            }
             
            27}
             
            28
               我們仔細(xì)一看,不對(duì),有重復(fù)的代碼,如何去除重復(fù)的代碼呢?我們可以提取這些代碼到一個(gè)獨(dú)立的方法,然后標(biāo)志這個(gè)方法為SetUp 屬性,這樣2個(gè)測(cè)試方法可以共享對(duì)操作數(shù)的初始化了,這里是改動(dòng)后的代碼: 
             1using System; 
             2using NUnit.Framework; 
             3  
             4namespace NUnitQuickStart 
             5
             6            [TestFixture] 
             7            public class NumersFixture 
             8            
             9                        private int a; 
            10                        private int b; 
            11                        [SetUp] 
            12                        public void InitializeOperands() 
            13                        
            14                                    a = 1
            15                                    b = 2
            16                        }
             
            17  
            18                        [Test] 
            19                        public void AddTwoNumbers() 
            20                        
            21                                    int sum=a+b; 
            22                                    Assert.AreEqual(sum,3); 
            23                        }
             
            24                        [Test] 
            25                        public void MultiplyTwoNumbers() 
            26                        
            27                                    int product = a * b; 
            28                                    Assert.AreEqual(2, product); 
            29                        }
             
            30  
            31            }
             
            32}
             
            33
               這樣NUnit將在執(zhí)行每個(gè)測(cè)試前執(zhí)行標(biāo)記SetUp屬性的方法.在本例中就是執(zhí)行InitializeOperands()方法.記住,這里這個(gè)方法必須為public,不然就會(huì)有以下錯(cuò)誤:Invalid Setup or TearDown method signature
            

            ExpectedException

            這里是一個(gè)驗(yàn)證這個(gè)假設(shè)的測(cè)試.有的時(shí)候,我們知道某些操作會(huì)有異常出現(xiàn),例如, 在實(shí)例中增加除法,某個(gè)操作被0除,拋出的異常和.NET文檔描述的一樣.參看以下源代碼.
            1[Test]
            2[ExpectedException(typeof(DivideByZeroException))]
            3public void DivideByZero()
            4{
            5   int zero = 0;
            6   int infinity = a/zero;
            7   Assert.Fail("Should have gotten an exception");
            8}

            9
               除了[Test]屬性之外, DivideByZero方法有另外一個(gè)客戶(hù)屬性: ExpectedException.在這個(gè)屬性里,你可以在執(zhí)行過(guò)程中捕獲你期望的異常類(lèi)型,例如在本例就是DivideByZeroException.如果這個(gè)方法在沒(méi)有拋出期望異常的情況下完成了,這個(gè)測(cè)試失敗.使用這個(gè)屬性幫助我們寫(xiě)程序員測(cè)試驗(yàn)證邊界條件(Boundary Conditions).

            Ignore 屬性

               由于種種原因,有一些測(cè)試我們不想運(yùn)行.當(dāng)然,這些原因可能包括你認(rèn)為這個(gè)測(cè)試還沒(méi)有完成,這個(gè)測(cè)試正在重構(gòu)之中,這個(gè)測(cè)試的需求不是太明確.但你有不想破壞測(cè)試,不然進(jìn)度條可是紅色的喲.怎么辦?使用Ignore屬性.你可以保持測(cè)試,但又不運(yùn)行它們.讓我們標(biāo)記MultiplyTwoNumbers測(cè)試方法為Ignore屬性:
            1[Test]
            2[Ignore("Multiplication is ignored")]
            3public void MultiplyTwoNumbers()
            4{
            5   int product = a * b;
            6   Assert.AreEqual(2, product);
            7}
               運(yùn)行測(cè)試,現(xiàn)在產(chǎn)生了下面的輸出(在圖5-1顯示):
             
            圖 5-1: 在一個(gè)程序員測(cè)試中使用 Ignore屬性
               Ignore屬性可以附加到一個(gè)獨(dú)立的測(cè)試方法,也可以附加到整個(gè)測(cè)試類(lèi)(TestFixture).如果Ignore屬性附加到TestFixture,所有在fixture的測(cè)試都被忽略.

            TestFixtureSetUp/TestFixtureTearDown

               有時(shí),一組測(cè)試需要的資源太昂貴.例如,數(shù)據(jù)庫(kù)連接可能是一個(gè)關(guān)鍵資源,在一個(gè)test fixture的每個(gè)測(cè)試中,打開(kāi)/關(guān)閉數(shù)據(jù)庫(kù)連接可能非常慢.這就是我在開(kāi)始提到的問(wèn)題.如何解決?NUnit有一對(duì)類(lèi)似于前面討論的SetUp/TearDown的屬性: TestFixtureSetUp/TestFixtureTearDown.正如他們名字表明的一樣,這些屬性用來(lái)標(biāo)記為整個(gè)test fixture初始化/釋放資源方法一次的方法.
               例如,如果你想為所有test fixture的測(cè)試共享相同的數(shù)據(jù)庫(kù)連接對(duì)象,我們可以寫(xiě)一個(gè)打開(kāi)數(shù)據(jù)庫(kù)連接的方法,標(biāo)記為TestFixtureSetUp屬性,編寫(xiě)另外一個(gè)關(guān)閉數(shù)據(jù)庫(kù)連接的方法,標(biāo)記為TestFixtureTearDown屬性.這里是描述這個(gè)的例子.
             1using NUnit.Framework;
             2
             3[TestFixture]
             4public class DatabaseFixture
             5{
             6   [TestFixtureSetUp]
             7   public void OpenConnection()
             8   {
             9      //open the connection to the database
            10   }

            11 
            12   [TestFixtureTearDown]
            13   public void CloseConnection()
            14   {
            15      //close the connection to the database
            16   }

            17   
            18   [SetUp]
            19   public void CreateDatabaseObjects()
            20   {
            21      //insert the records into the database table
            22   }

            23 
            24   [TearDown]
            25   public void DeleteDatabaseObjects()
            26   {
            27      //remove the inserted records from the database table
            28   }

            29 
            30   [Test]
            31   public void ReadOneObject()
            32   {
            33      //load one record using the open database connection
            34   }

            35 
            36   [Test]
            37   public void ReadManyObjects()
            38   {
            39      //load many records using the open database connection
            40   }

            41}

            42
            43

            Test Suite

               Test Suite是test case或其他test suite的集合. 合成(Composite),模式描述了test case和test suite之間的關(guān)系.
             參考來(lái)自NUnit的關(guān)于Suite的代碼
            Suite Attribute

             1namespace NUnit.Tests
             2{
             3using System;
             4  using NUnit.Framework;
             5 
             6
             7
             8  public class AllTests
             9  {
            10    [Suite]
            11    public static TestSuite Suite
            12    {
            13      get
            14      {
            15        TestSuite suite = new TestSuite("All Tests");
            16        suite.Add(new OneTestCase());
            17        suite.Add(new Assemblies.AssemblyTests());
            18        suite.Add(new AssertionTest());
            19        return suite;
            20      }

            21    }

            22  }

            23}
             
            24
            Category屬性

             對(duì)于測(cè)試來(lái)說(shuō),你有的時(shí)候需要將之分類(lèi),此屬性正好就是用來(lái)解決這個(gè)問(wèn)題的。
             你可以選擇你需要運(yùn)行的測(cè)試類(lèi)目錄,也可以選擇除了這些目錄之外的測(cè)試都可以運(yùn)行。在命令行環(huán)境里 /include 和/exclude來(lái)實(shí)現(xiàn)。在GUI環(huán)境下,就更簡(jiǎn)單了,選擇左邊工作域里的Catagories Tab,選擇Add和Remove既可以了。
            在上面的例子上做了一些改善,代碼如下:
             1using System; 
             2using NUnit.Framework; 
             3  
             4namespace NUnitQuickStart 
             5
             6            [TestFixture] 
             7            public class NumersFixture 
             8            
             9                        private int a; 
            10                        private int b; 
            11                        [SetUp] 
            12                        public  void InitializeOperands() 
            13                        
            14                                    a = 1
            15                                    b = 2
            16                        }
             
            17  
            18                        [Test] 
            19                        [Category("Numbers")] 
            20                        public void AddTwoNumbers() 
            21                        
            22                                    int sum=a+b; 
            23                                    Assert.AreEqual(sum,3); 
            24                        }
             
            25                        
            26                        [Test] 
            27                [Category("Exception")] 
            28                        [ExpectedException(typeof(DivideByZeroException))] 
            29                        public void DivideByZero() 
            30                        
            31                                    int zero = 0
            32                                    int infinity = a/zero; 
            33                                    Assert.Fail("Should have gotten an exception"); 
            34                        }
             
            35                        [Test] 
            36                        [Ignore("Multiplication is ignored")] 
            37                        [Category("Numbers")] 
            38                        public void MultiplyTwoNumbers() 
            39                        
            40                                    int product = a * b; 
            41                                    Assert.AreEqual(2, product); 
            42                        }
             
            43  
            44               }
             
            45
                    NUnit-GUI界面如圖5-2:
             
            
            圖5-2:使用Catagories屬性的界面
            

            Explicit屬性

            本屬性忽略一個(gè)test和test fixture,直到它們顯式的選擇執(zhí)行。如果test和test fixture在執(zhí)行的過(guò)程中被發(fā)現(xiàn),就忽略他們。所以,這樣一來(lái)進(jìn)度條顯示為黃色,因?yàn)橛衪est或test fixture忽略了。
             例如:
              
             1
             2                        [Test,Explicit] 
             3                        [Category("Exception")] 
             4                        [ExpectedException(typeof(DivideByZeroException))] 
             5                        public void DivideByZero() 
             6                        
             7                                    int zero = 0
             8                                    int infinity = a/zero; 
             9                                    Assert.Fail("Should have gotten an exception"); 
            10                        }

            11
                為什么會(huì)設(shè)計(jì)成這樣呢?原因是Ingore屬性忽略了某個(gè)test或test fixture,那么他們你再想調(diào)用執(zhí)行是不可能的。那么萬(wàn)一有一天我想調(diào)用被忽略的test或test fixture怎么辦,就用Explicit屬性了。我想這就是其中的原因吧。

            Expected Exception屬性

              期望在運(yùn)行時(shí)拋出一個(gè)期望的異常,如果是,則測(cè)試通過(guò),否則不通過(guò)。
            參看下面的例子:
             1[Test] 
             2[ExpectedException(typeofInvalidOperationException))] 
             3public void ExpectAnException() 
             4 
             5   int zero = 0
             6   int infinity = a/zero; 
             7   Assert.Fail("Should have gotten an exception"); 
             8                       
             9 }
             
            10
                在本測(cè)試中,應(yīng)該拋出DivideByZeroException,但是期望的是InvalidOperationException,所以不能通過(guò)。如果我們將[ExpectedException(typeof(InvalidOperationException))]改為[ExpectedException(typeof(DivideByZeroException))],本測(cè)試通過(guò)。

            5 . 測(cè)試生命周期合約

               如果記得test case的定義,其中一個(gè)屬性是測(cè)試的獨(dú)立性或隔離性.SetUp/TearDown方法提供達(dá)到測(cè)試隔離性的目的.SetUp確保共享的資源在每個(gè)測(cè)試運(yùn)行前正確初始化,TearDown確保沒(méi)有運(yùn)行測(cè)試產(chǎn)生的遺留副作用. TestFixtureSetUp/TestFixtureTearDown同樣提供相同的目的,但是卻在test fixture范圍里,我們剛才描述的內(nèi)容組成了測(cè)試框架的運(yùn)行時(shí)容器(test runner)和你寫(xiě)的測(cè)試之間的生命周期合約(life-cycle contract).
               為了描述這個(gè)合約,我們寫(xiě)一個(gè)簡(jiǎn)單的測(cè)試來(lái)說(shuō)明什么方法調(diào)用了,怎么合適調(diào)用的.這里是代碼:
             1using System;
             2using NUnit.Framework;
             3[TestFixture]
             4public class LifeCycleContractFixture
             5{
             6   [TestFixtureSetUp]
             7   public void FixtureSetUp()
             8   {
             9      Console.Out.WriteLine("FixtureSetUp");
            10   }

            11 
            12   [TestFixtureTearDown]
            13   public void FixtureTearDown()
            14   {
            15      Console.Out.WriteLine("FixtureTearDown");
            16   }

            17   
            18   [SetUp]
            19   public void SetUp()
            20   {
            21      Console.Out.WriteLine("SetUp");
            22   }

            23
            24   [TearDown]
            25   public void TearDown()
            26   {
            27      Console.Out.WriteLine("TearDown");
            28   }

            29 
            30   [Test]
            31   public void Test1()
            32   {
            33      Console.Out.WriteLine("Test 1");
            34   }

            35
            36   [Test]
            37   public void Test2()
            38   {
            39      Console.Out.WriteLine("Test 2");
            40   }

            41
            42}

            43
            44
            當(dāng)編譯和運(yùn)行這個(gè)測(cè)試,可以在System.Console窗口看到下面的輸出:
            FixtureSetUp
            SetUp
            Test 
            1
            TearDown
            SetUp
            Test 
            2
            TearDown
            FixtureTearDown
               可以看到, SetUp/TearDown方法調(diào)用在每個(gè)測(cè)試方法的前后. 整個(gè)fixture調(diào)用一次TestFixtureSetUp/TestFixtureTearDown方法.
             
             下載:
            1)NUnit的應(yīng)用文檔 下載
            2)本問(wèn)的PDF版 下載
            3)本文的源代碼 下載 
                參考
            1)      http://www.nunit.org
            2)      James W. Newkirk and Alexei A. Vorontsov ,Test-Driven Development in Microsoft .NET,Microsoft Press,2003
            3)      http://www.testdriven.com
            4)      Kent Beck, Test-Driven Development: By Example ,Addison-Wesley Professional, 2003
            5)      Andrew Hunt ,David Thomas ,Pragmatic Unit Testing  In   C#  With NUnit
            6)      NUnit中文文檔:http://www.36sign.com/nunit

            posted on 2008-04-30 21:13 Mike Song 閱讀(362) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            久久久久久久综合日本亚洲| 久久国产香蕉一区精品| 日韩精品久久久久久久电影| 草草久久久无码国产专区| 久久久国产精品福利免费| 国内精品久久九九国产精品| 国产精品99久久99久久久| 久久久无码一区二区三区| 久久久久亚洲精品天堂| 久久久久99精品成人片试看| 久久99国产综合精品女同| 国产综合久久久久| 久久91精品国产91久久户| 久久国产亚洲精品麻豆| 99久久国产综合精品成人影院| 国产精品免费久久久久电影网| 国产精品嫩草影院久久| 久久久久久无码国产精品中文字幕| 久久久久久国产精品美女| 久久伊人五月天论坛| 亚洲欧洲中文日韩久久AV乱码| 久久99热这里只有精品66| 亚洲精品乱码久久久久久蜜桃不卡| 久久久久亚洲AV无码专区首JN | 人妻无码中文久久久久专区| 无遮挡粉嫩小泬久久久久久久| 久久精品午夜一区二区福利| av午夜福利一片免费看久久| 91精品国产91久久| 亚洲国产精品嫩草影院久久| 无码人妻久久一区二区三区 | 亚洲级αV无码毛片久久精品| 熟妇人妻久久中文字幕| 久久福利青草精品资源站| 国内精品久久久久影院网站| 四虎影视久久久免费| 久久亚洲精精品中文字幕| 国产精品久久久天天影视| 精品人妻伦九区久久AAA片69| 久久久久久亚洲精品影院| 久久国产亚洲高清观看|