NUNIT1. NUNIT簡介 NUnit是一個(gè)為Net準(zhǔn)備的自動(dòng)化單元測(cè)試框架,它的作用就是幫助你方便的完成單元測(cè)試工作,同鼎鼎有名的JUnit一樣,都是xUnit家族的成員。它的下載地址是:http://www.。 NUnit Framework(NUnit 單元測(cè)試框架)簡介
TestFixture Attribute簡介 使用TextFixture Attribute的class需要符合另一項(xiàng)唯一附加的限制,就是需要有一個(gè)public的default constructor(或者是沒有定義任何的constructor,這其實(shí)是相同的意思)。
TestFixtureSetUp 和TestFixtureTearDown簡介 底下這段程序代碼示范了如何使用TestFixtureSetUp/TestFixtureTearDown ````[TestFixtureTearDown] ``` [SetUp] [Test] Test Attribute簡介 SetUp 和 Teardown Attributes簡介 ExpectedException Attributes簡介 如果上面的程序被執(zhí)行的時(shí)候,如果一旦exception發(fā)生,而且這個(gè)exception的type(類型信息)是 InvalidOperationException 的話,這個(gè)test就會(huì)順利通過驗(yàn)證。如果你預(yù)期你的程序代碼會(huì)產(chǎn)生多個(gè)exception的話,你也可以一次使用多個(gè) ExpectedException attribute。但是,一個(gè)test method應(yīng)該只測(cè)試一件事情,一次測(cè)試多個(gè)功能是不好的做法,你應(yīng)該盡量避免之。另外,這個(gè)attributes并不會(huì)檢查inheirtance的 關(guān)系,也就是說,如果你的程序代碼產(chǎn)生的exception是繼承自InvalidOperationException 的subclass(子類化)的話,這個(gè)test執(zhí)行的時(shí)候?qū)⒉粫?huì)通過驗(yàn)證。簡而言之,當(dāng)你使用這個(gè)attribute的時(shí)候,你要明確的指明所預(yù)期的 exception是哪個(gè)type(類型信息)的。 Ignore Attributes簡介 namespace UnitTestingExamples NUnit Assert Class簡介 好,現(xiàn)在我們已經(jīng)討論過寫Unit Tests的基本步驟及方法,現(xiàn)在讓我們來看看如何執(zhí)行你所寫的Unit Tests。事實(shí)上非常簡單。NUnit里面有兩個(gè)已經(jīng)寫好的Test Runner applications:一個(gè)是窗口GUI程序,一個(gè)是console XML(命令列)程序。你可以自由選擇你所喜歡的方式,基本上是沒有什么差別的。 2. 基本用法 a. 目前項(xiàng)目中的用法 例1: 初始化 [SetUp] public void InitializeOperands() { pub=new PUB(); } 可以對(duì)需要初始化才能使用的類,進(jìn)行初始化。例如,與數(shù)據(jù)庫相關(guān)的操作。 例2: 簡單測(cè)試 [Test] public void ReqToRes_Test() { string reqfile="REQ-CKI-CIQU-123456789-20060317.csv"; string resfile=null; bool returnVal=pub.ReQToRes(reqfile,ref resfile); Assert.IsFalse(returnVal); } 例3: 對(duì)拋出的異常做測(cè)試 [Test] [ExpectedException(typeof(Exception))] public void Check_bgdh_test() { string b="125698300"; ciq.Check_bgdh(b); } b. 未使用的用法 [TestFixtureSetUp] [TestFixtureTearDown] 當(dāng)整個(gè)測(cè)試框架都需要引用某個(gè)類是,可以在 [TestFixtureSetUp]中將它初始化,然后在[TestFixtureTearDown]中將它釋放。 c. 不建議使用: [Ignore("We‘re skipping this one for now.")],因?yàn)檫@樣可能會(huì)忽略這個(gè)被測(cè)函數(shù)。 3. 解決方案 a.新生成一個(gè)解決方案 b.添加測(cè)試項(xiàng)目 c.設(shè)置屬性 d.在NUNIT-GUI環(huán)境下調(diào)試 通過【運(yùn)行】按鈕,在NUNIT-GUI下調(diào)試 e.注意:這種方法在調(diào)試過程中如果發(fā)生錯(cuò)誤,必須在原來的項(xiàng)目中修改,然后再將源文件復(fù)制到NUNIT項(xiàng)目中再進(jìn)行測(cè)試。否則的話,容易發(fā)生混淆。 4. 其它的解決方案 a. 在原有的解決方案上新增加一個(gè)項(xiàng)目 b. 添加一個(gè)測(cè)試類 c. 導(dǎo)入所需要的引用 包括測(cè)試類:NUNIT.FRAMEWORD和需要被測(cè)試的項(xiàng)目 d. 添加引用: e. 接下來就可以測(cè)試了。 f.這種測(cè)試方法比較適用于測(cè)試人員。 5. 測(cè)試用例 a. 條件判斷 例1:對(duì)參數(shù)為NULL值進(jìn)行測(cè)試 [Test] public void CheckFileName_Test_null() { string reqfile=null; string asktype=null; bool returnVal=pub.CheckFileName(ref reqfile,ref asktype); Console.WriteLine(asktype); Assert.IsFalse(returnVal); } 例2:對(duì)參數(shù)為空字符串進(jìn)行測(cè)試 [Test] public void CheckFileName_Test_empty() { string reqfile=""; string asktype="DCL"; bool returnVal=pub.CheckFileName(ref reqfile,ref asktype); Console.WriteLine(asktype); Assert.IsFalse(returnVal); } 例3:對(duì)不合法的參數(shù)進(jìn)行測(cè)試(報(bào)關(guān)單號(hào)不足9位) [Test] public void CheckFileName_Test1() { string reqfile="REQ-CKI-DCL-12345679-20060317.csv"; string asktype= "DCL"; bool returnVal=pub.CheckFileName(ref reqfile,ref asktype); Console.WriteLine(asktype); Assert.IsFalse(returnVal); // Assert.IsTrue(returnVal); } 例4:對(duì)不合法的參數(shù)進(jìn)行測(cè)試2(日期長度不符合) [Test] public void CheckFileName_Test2() { string reqfile="REQ-CKI-DCL-123456789-2006031.csv"; string asktype= "DCL"; bool returnVal=pub.CheckFileName(ref reqfile,ref asktype); Console.WriteLine(asktype); Assert.IsFalse(returnVal); } b. 數(shù)據(jù)庫操作 [Test] public void getConnectionSQl_test() { bool returnVal=pub.GetConnectionSQL(); Assert.IsTrue(returnVal); } 對(duì)數(shù)據(jù)庫操作的測(cè)試,需要對(duì)數(shù)據(jù)庫中數(shù)據(jù)進(jìn)行修改,才可以對(duì)不同的數(shù)據(jù)進(jìn)行測(cè)試。 6.對(duì)今后的項(xiàng)目提出的一些建議和改善: a. 需求分析 首先,將項(xiàng)目需求進(jìn)行分析,從中搞清楚輸入和輸出,流程圖,錯(cuò)誤信息等。最好將它文檔化。 例:FTP處理主要分為幾個(gè)功能 1. 顯示FTP目錄下需要處理的文件名:public string[] getFileList(string mask) 2. 將選中的文件下載到本地:public void download(string remFileName,string path) 輸入:需要下載的文件名:string remFileName,路徑:string path 輸出:在本地生成一個(gè)同名的文件 3. 將生成的回執(zhí)文件上傳:public void upload(string fileName) 將上傳的回執(zhí)文件改名:public void renameRemoteFile(string oldFileName,string newFileName) 4. 將請(qǐng)求文件在FTP上刪除:public void deleteRemoteFile(string fileName) b. 函數(shù)細(xì)化 例:將選中的文件下載到本地:public void download(string remFileName,string path) 其中對(duì)下載作了3個(gè)重載函數(shù),以適應(yīng)于不同的需要。 a. public void download(string remFileName,string path) :下載到本地路徑 b. public void download(string remFileName,string path,string locFileName) :下載到本地路徑,支持改名 c. public void download(string remFileName,//遠(yuǎn)程文件名 string locFileName,//本地文件名 Boolean resume)//是否續(xù)傳 :下載到本地路徑,支持改名,支持續(xù)傳 其中前兩個(gè)函數(shù)是對(duì)第三個(gè)函數(shù)的變種,都是調(diào)用第三個(gè)函數(shù),只是限制了某些功能。這樣可以增加函數(shù)的靈活性。 其中DOWNLOAD函數(shù)使用了如下幾個(gè)獨(dú)立的子函數(shù)來完成的 1. LOGIN if(!logined) { login(); } 2. 生成SOCKET連接 Socket cSocket = createDataSocket(); 3. 發(fā)送下載命令 sendCommand("RETR " + remFileName); 4. 接受數(shù)據(jù) while(true) //開始下載 { bytes = cSocket.Receive(buffer, buffer.Length, 0); output.Write(buffer,0,bytes); if(bytes <= 0) { break; } }//while 5. 判斷是否下載完成 if (!isDownComplete()) { throw new Exception(replay); } c. 異常處理 1. 自定義異常 a. 實(shí)現(xiàn)自己的異常類 MyImportantException 2. 異常的分類處理:引用上面一個(gè)例子,FTP下載是一個(gè)公用的函數(shù),而通過對(duì)它的細(xì)分,可以將它分為幾個(gè)較小的獨(dú)立的私有函數(shù)。所以自定義異常就可以在這里發(fā)揮作用,每個(gè)獨(dú)立的私有函數(shù)都可以拋出各自定義的異常,而在FTP下載這個(gè)公有函數(shù)中將捕獲被拋出的異常,并對(duì)它們進(jìn)行處理或者拋給它的上一級(jí)函數(shù)。 d. 通過對(duì)函數(shù)的細(xì)化,分解出一個(gè)個(gè)獨(dú)立的、只完成特定功能的函數(shù)。并且通過結(jié)構(gòu)化的異常處理可以使測(cè)試簡單化。 7. 總結(jié) a.如果將UNIT作為測(cè)試用途的化,它可以起到自動(dòng)化的作用,減輕測(cè)試人員的工作量。如果發(fā)生功能改變或BUG修正,需要修改源代碼時(shí),利用自動(dòng)化測(cè)試可以大量減輕測(cè)試人員工作量。 建議:提供功能函數(shù)的接口給測(cè)試人員,這樣在不改變函數(shù)名的情況下,僅修改函數(shù)內(nèi)部的邏輯。而測(cè)試人員僅需要增加或修改測(cè)試用例,就可以保持新版本的測(cè)試。 b.如果將UNIT作為測(cè)試驅(qū)動(dòng)的話,就使得程序員對(duì)測(cè)試給予足夠的重視,從而可以編寫較高質(zhì)量的程序。 |
|