《電子技術應用》
您所在的位置:首頁 > 測試測量 > 設計應用 > 數據驅動測試在Nunit框架中的應用
數據驅動測試在Nunit框架中的應用
來源:微型機與應用2012年第22期
王 敏1, 陳亞光2
(1. 武昌理工學院 信息工程學院, 湖北 武漢 430223; 2. 中南民族大學 生物醫學工程學
摘要: 為了解決單元測試工具Nunit本身不支持數據驅動測試的問題,提出了在Nunit框架下實現數據驅動測試的方法。該方法首先將測試類所使用的測試數據基本信息設定在ini文件中,將輸入數據及預期結果存放于Excel文件中。隨后通過屬性標簽[TestFixtureSetUp]標記的方法動態讀取ini文件中的基本信息,再根據這些基本信息讀取Excel文件中的測試數據,并將測試數據保存于自定義的結構體數組中供各測試方法使用。該方法有效地實現了測試數據與測試腳本的分離,能降低測試腳本的維護工作量,提高測試效率。
Abstract:
Key words :

摘  要: 為了解決單元測試工具Nunit本身不支持數據驅動測試的問題,提出了在Nunit框架下實現數據驅動測試的方法。該方法首先將測試類所使用的測試數據基本信息設定在ini文件中,將輸入數據及預期結果存放于Excel文件中。隨后通過屬性標簽[TestFixtureSetUp]標記的方法動態讀取ini文件中的基本信息,再根據這些基本信息讀取Excel文件中的測試數據,并將測試數據保存于自定義的結構體數組中供各測試方法使用。該方法有效地實現了測試數據與測試腳本的分離,能降低測試腳本的維護工作量,提高測試效率。
關鍵詞: 單元測試; Nunit框架; 測試腳本; 測試數據

    軟件測試是保證軟件質量的重要手段,作為軟件測試基礎的單元測試是軟件開發過程中最低級的測試活動。據業界統計,單元測試一般可以發現大約80%的軟件缺陷[1]。由于軟件缺陷發現得越早,其修復的代價就越小,因此,單元測試在軟件測試過程中占據著非常重要的地位,有效地實施單元測試能有效節約后續測試時間、降低測試成本、保證軟件質量。
    Nunit是微軟.Net平臺下的單元測試框架,也是在.Net平臺下進行測試驅動開發的重要工具;其提供的圖形用戶接口GUI操作簡單、內容直觀,因此Nunit被廣泛地運用于.Net平臺項目的單元測試中。利用Nunit進行單元測試,首先要進行腳本開發,目前常用的方法是將測試數據以常量的方式賦值給變量,再由變量參與測試[2-3]。采用這種方式,測試數據與測試腳本共存于一個測試腳本文件中,不利于測試腳本的維護。而測試腳本的維護是自動化測試的重要環節,適當地調整和增強測試腳本,能提高測試腳本的靈活性以及應對測試對象變更的能力,數據驅動方式的測試腳本開發是解決這類問題的重要手段[4]。由于Nunit框架本身并不具備數據驅動測試的功能,因此需要通過增強測試腳本的功能來實現Nunit框架下的數據驅動測試。為此,本文提出一種測試設計方法,將測試用例的輸入數據、預期結果及執行條件編寫在Excel工作簿中,工作簿中每一個工作表的數據對應一個測試類;工作簿存放的位置、測試類對應的工作表名、輸入數據數目及預期結果數目等信息按一定格式保存于執行路徑下的ini文件中。在測試腳本中,利用Nunit的[TestFixtureSetUp]屬性標簽,在該標簽標記的方法中實現測試類所有測試數據的一次性讀入,并將其保存于自定義的結構體數組中,供各測試方法使用,在后續測試方法的腳本編寫中,只需按結構體數組下標獲取測試數據及預期結果便能完成測試腳本的開發;測試執行時將按照Excel文件中設計的數據自動執行測試腳本。這一測試設計方法能有效地分離測試腳本和測試數據,從而降低測試腳本的維護工作量。
1 數據驅動測試的設計思路
    數據驅動測試是一種數據被包含在輸入測試數據文件中,并且以數據來控制自動化測試腳本執行的流程和動作的測試[5]。在Nunit框架中,[TestFixtureSetUp]和[SetUp]屬性標簽標記的方法分別在測試類和各測試方法執行前被執行,[Test]屬性標簽標記的方法按其在腳本中的先后順序自動執行;此外,通過Nunit的GUI界面,可以指定被執行的方法,因此Nunit自身已經具備控制測試腳本執行流程的功能。這里主要從用數據驅動腳本的動作出發來實現數據驅動測試。
  數據驅動測試使用存檔的測試數據來驅動自動化測試過程,這些數據通常以簡單的文本文件或Excel文件形式存在[5]。鑒于Excel文件具有以表格形式呈現、結構清晰直觀的特點,本文采用Excel的工作表來存儲測試數據。同時,為使測試腳本具有較高的靈活性,將測試數據文件的存取路徑、測試數據所在的工作表名等信息存放于ini文件中,以便在測試環境和數據發生改變時,測試腳本可以保持不變,從而降低測試腳本的維護成本。
1.1 Excel文件格式的設計
    圖1為Excel文件結構與測試類及測試方法之間的對應關系圖,圖中的數據是根據Nunit自帶的一個實例Moneybag類所做的部分測試數據。

    圖1中,工作簿Moneytest.xls中的工作表Moneytest用來存放測試類Moneytest中各測試方法所需的數據。由于各測試方法常常使用一些公共的輸入數據來進行測試驗證,因此將公共數據設定在第一行,從第二行數據開始每一行數據對應一個測試方法,每一個單元格存放一個基本數據(字符串類型或數值)。結構數據類型都可以看成是基本數據類型的組合,一個結構數據類型可分成多個單元格來存放。由于每一個測試方法所需的輸入和預期值數目各不相同,在測試數據設計時,可按需要增減工作表列的數目來增減輸入和預期值的數目(圖1中3~6行的A-H列為空,是因為3~6行對應的測試方法全部采用公共輸入數據)。測試數據的最后一列為測試說明,用于對測試條件等輔助信息加以說明,以供測試人員或維護人員參考,測試腳本不讀取該列數據。
1.2 ini文件的設計
    使用ini文件是為了使這一實現方法具有較高的靈活性,最大限度地減少因測試環境和測試數據的變化帶來的測試腳本的維護工作量。這里約定ini文件以標記的測試類命名,并且保存于執行文件所在目錄下,這樣可通過編程來動態讀取路徑。因此,除了ini文件名外,其他所有數據的來源都是通過測試腳本執行動態獲取的,這一實現方法能達到較高程度的測試腳本與測試數據的分離。
    ini文件設計如下:
     [FILE]
          path= "D:\NUNIT\Moneytest.xls"
          sheet= [Moneytest$]
     [DATA]
          input=8
          except=4
     [ROWS]
          Common=0
          BagSimpleAdd=1
          BagSubtract=2
          BagMultiply=3
        BagNegate=4
    節[FILE]用于存放Excel數據文件信息,參數path的值表示數據文件存放的路徑,參數sheet的值表示測試數據所在的工作表名;節[DATA]用于存放輸入數據和預期值的數目,這里按該測試類中使用輸入數據和預期值數目最多的方法進行設置,用于動態定義結構體內數組的維數,這樣定義會損失一定的數組空間,但給測試腳本的編寫帶來了方便;節[ROWS]用于存放每個測試方法對應的測試數據所在的行編號(結構體數組下標),在各測試方法中通過讀取ini文件中的行編號來取得對應的測試數據,Common=0表示將公用數據設在數據表第一行,讀入到下標為0的數組中。
2 數據驅動測試的實現
    Nunit采用屬性標簽來標記測試類和方法,其中[TestFixture]用于標記測試類,[Test]、[SetUp]、[TestFixtureSetUp]用于標記測試方法。[SetUp]標記的方法是為了避免代碼的冗余,該方法將各測試方法中的重復代碼提取出來,組織成一個共用的方法,在每個[Test]標記的測試方法執行前被執行一次,與它成對使用的是[TearDown]屬性,用來釋放[SetUp]中初始化的變量。[TestFixtureSetUp]與[SetUp]屬性類似,但此屬性標記的方法用來實現整個測試類的初始化,它在整個測試類執行前執行一次,與它成對使用的是[TestFixtureTearDown]屬性,用來釋放[TestFixtureSetUp]中初始化的變量。
    在本設計中,測試數據被存儲在外部數據文件中,每一個方法執行前都需要外部文件中的測試數據,如果將讀取外部文件的操作分別寫到各個測試方法中,這無疑會產生大量冗余代碼,也會增加I/O方面的開銷;如果將這部分處理寫到[SetUp]屬性方法中,可減少測試腳本中重復代碼的數量,但I/O方面的開銷與前一種方法相比,沒有任何改善。故本設計將測試數據讀取的代碼編寫在[TestFixtureSetUp]屬性標記的方法中,通過自定義一個結構體,將測試數據一次性讀出并存放于結構體數組中,即在整個測試類的方法執行之前執行一次測試數據的讀取操作。這樣,既能減少測試腳本中重復代碼的數量,也能減少I/O方面的開銷。
2.1 自定義結構體的實現
    public struct testdata
       {
                public string[] strIn ;
                public string[] strExcept;
       }
       上面是采用C#定義的結構體testdata,其中包含兩個字符串類型的動態數組,分別用來存放各測試方法的輸入數據和預期結果。因為測試類最大的輸入數據和預期結果數目在測試用例維護時可能發生變化,故采用定義動態數組的方式。
2.2 測試類初始化的實現
    [TestFixtureSetUp]屬性標記的方法用于整個測試類的初始化,其處理流程設計如圖2所示。

    過程①中讀取[FILE]和[DATA]節中的值,用于定位測試數據文件和定義結構體數組維數;過程②按行列依次循環,將數據表中的數據依次全部讀入結構體數組;過程③初始化各測試方法的公用數據,下面是按照本文提出的方法,以Nunit自帶的樣例測試腳本MoneyTest.cs為例對公共輸入數據進行設定的相關代碼:
    f12CHF = new Money(Convert.ToInt32(tdTest[i].strIn[0]), tdTest[i].strIn[1]);
    f7USD = new Money(Convert.ToInt32(tdTest[i].strIn[2]), tdTest[i].strIn[3]);
    f14CHF = new Money(Convert.ToInt32(tdTest[i].strIn[4]), tdTest[i].strIn[5]);
    f21USD = new Money(Convert.ToInt32(tdTest[i].strIn[6]), tdTest[i].strIn[7]);
    fMB1 = new MoneyBag(f12CHF, f7USD);
    fMB2 = new MoneyBag(f14CHF, f21USD);
    如果約定下標為0的結構體數組中存放公共測試數據,則在上面的代碼前可直接將i賦值為0,也可讀取ini文件的Common值來設定i值。
2.3 自定義方法的實現
    每一個方法執行之前都需要讀取結構體數組中對應行的數據,雖然讀取數據的代碼可以寫在各測試方法中,但這無疑會產生重復代碼。通過分析各測試方法讀取數據的相似部分,可將這部分代碼寫成一個公用方法,[SetUp]中定義的方法能保證各方法執行之前自動執行一次,但是該方法不能帶參數。因此,這里自定義一個帶參數的方法供各測試方法調用。同樣以Moneybag類的測試為例,該測試類中,各方法的輸入基本采用公共數據,各方法的預期結果各不相同,因此各方法均有一個讀取預期結果的公共處理,將這部分處理用自定義方法實現,參數i為各方法對應的測試數據的數組下標。代碼如下:
    private void SetValue(int i)
    {
    mexcept1 = new Money(Convert.ToInt32(tdTest[i].strExcept[0]), tdTest[i].strExcept[1]);
    mexcept2= new Money(Convert.ToInt32(tdTest[i].strExcept[2]), tdTest[i].strExcept[3]);
    mbexcept = new MoneyBag(mexcept1, mexcept2);
    }
     數據表中的數據全部以字符串類型讀入構造體數組中,使用時,根據具體情況將字符串類型轉換為對應數據類型參與測試。公共處理以外的個性數據讀取可在各測試方法中實現。
2.4 各測試方法的實現
    將Nunit自帶的樣例測試腳本按照本文提出的方法進行改編,下面是實現單一貨幣錢包加法的改編腳本(其他方法基本類似):
    [Test]
    public void BagSimpleAdd()
    {
    int intI = GetPrivateProfileString("ROWS", "BagSimpleAdd", "", tmpRow, 500, striniPath + "\\moneytest.ini");
    int i = Convert.ToInt32(Convert.ToString(tmpRow));
    SetValue(i);
    Assert.AreEqual(mbexcept, fMB1.Add(f14CHF));
    }

 


    利用本文提出的方法對Nunit自帶測試類Monytest.cs中的所有方法進行改編,執行結果與自帶測試類一致。與原來的方法相比較,本文提出的方法實現了測試腳本與測試數據的分離,對測試用例的維護基本可通過對Excel數據文件和ini文件的維護來實現,從而降低了測試腳本維護過程中產生的維護成本。在后續的研究中,將根據本文提出的方法,進一步探索測試腳本自動生成的實現,以進一步提高測試腳本的開發效率。
參考文獻
[1] 劉德寶.軟件測試工程師培訓教材[M].北京:科學出版社,2009.
[2] 林勤花.使用NUnit在.net編程中進行單元測試[J].科技信息,2008(24):410-411.
[3] 陸復名. NUnit.NET項目測試點評[J].程序員,2004(11):128-129.
[4] 陳技能.QTP自動化測試實踐[M]. 北京:電子工業出版社,2009.
[5] 劉曉丹,武君勝,劉博.基于數據驅動的自動化測試平臺設計[J].科學技術與工程,2008,8(3):779-782.

此內容為AET網站原創,未經授權禁止轉載。
主站蜘蛛池模板: 真实国产精品视频国产网 | 男女男在线观看视频网站 | 亚洲日本中文字幕一本 | 色伦网| 黄免费观看 | 性欧美暴力猛交xxxxx高清 | 日韩专区在线 | 黄色免费看片网站 | 手机看片精品高清国产日韩 | 国产毛片久久国产 | 精品欧美 | 97青草香蕉依人在线播放 | 人人做天天爱夜夜爽中字 | 亚洲国产成人精品一区91 | 香蕉网站99视频丝瓜视频 | 人人艹人人艹 | 欧美成人看片一区二区三区尤物 | 成人一级黄色毛片 | 免费的黄网站 | 玖玖在线精品 | 中国三级毛片 | 58av国产精品 | 免费播放国产性色生活片 | 青草草在线 | 成人一a毛片免费视频 | 天天摸天天做 | 一级毛片在线免费视频 | 国产日韩精品欧美一区喷水 | 欧美成 人激情视频 | 成人黄网大全在线观看 | 91麻豆精品国产 | 三级黄色片在线观看 | 狠狠操网址 | 成人福利视频网址 | 黄色在线观看视频 | 日韩福利影视 | www黄色网址 | 国产欧美日韩综合二区三区 | 人人澡天天澡夜夜澡 | 一区二区免费在线观看 | 伊人网综合视频 |