• <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>

            使用 Visual Studio 2005 Team System 進(jìn)行單元測(cè)試

            原文地址

            使用 Visual Studio 2005 Team System 進(jìn)行單元測(cè)試并生成用于 Unit Test Framework 的源代碼

            發(fā)布日期 : 11/10/2005 | 更新日期 : 11/10/2005

            Scott Dockendorf
            Telligent Systems, Inc.

            適用于:
            Microsoft Visual Studio 2005 Team System Beta 2
            Team Architect & Team Test Editions
            Microsoft Visual C# 2005

            摘要: Scott 詳細(xì)介紹自動(dòng)化單元測(cè)試的基本內(nèi)容,以及由 Microsoft Visual Studio 2005 Team System 提供的 Unit Test Framework 中包含的代碼生成引擎。

            本頁(yè)內(nèi)容

            簡(jiǎn)介 簡(jiǎn)介
            重新思考單元測(cè)試 重新思考單元測(cè)試
            輸入自動(dòng)化單元測(cè)試 輸入自動(dòng)化單元測(cè)試
            為什么生成代碼? 為什么生成代碼?
            讓我們生成一些代碼吧! 讓我們生成一些代碼吧!
            生成了什么? 生成了什么?
            生成后:我現(xiàn)在需要做什么? 生成后:我現(xiàn)在需要做什么?
            重新生成單元測(cè)試代碼 重新生成單元測(cè)試代碼
            自動(dòng)化單元測(cè)試建議 自動(dòng)化單元測(cè)試建議
            小結(jié) 小結(jié)

            簡(jiǎn)介

            隨著業(yè)務(wù)的革新和發(fā)展,運(yùn)行它們的系統(tǒng)也需要進(jìn)行更新。隨業(yè)務(wù)的發(fā)展、革新以及與合作伙伴、客戶和供應(yīng)商的結(jié)合,這些系統(tǒng)將在復(fù)雜性方面持續(xù)擴(kuò)增。

            這種復(fù)雜性迫使 IT 的領(lǐng)導(dǎo)者們?cè)陂_(kāi)發(fā)過(guò)程中(即,在實(shí)現(xiàn)之前)確保質(zhì)量。有一種方法可使開(kāi)發(fā)人員減少進(jìn)入 QA 環(huán)節(jié)的故障數(shù)量,即,針對(duì)自定義代碼嚴(yán)格執(zhí)行自動(dòng)化單元測(cè)試。在開(kāi)發(fā)過(guò)程中強(qiáng)制使用自動(dòng)化單元測(cè)試可為團(tuán)隊(duì)成員提供有關(guān)如何使用自定義代碼的示例(這些示例易于使用并自行記錄)。

            使用結(jié)構(gòu)化、自動(dòng)化單元測(cè)試面臨的挑戰(zhàn)之一是完成這些任務(wù)所需的代碼總數(shù)。(測(cè)試代碼需要使用大量代碼!)代碼生成的概念(簡(jiǎn)單定義為“創(chuàng)建軟件的軟件”)正隨著時(shí)間的快速推移而逐漸深入到團(tuán)隊(duì) IT 開(kāi)發(fā)之中。有些人認(rèn)為代碼生成有助于縮短“推向市場(chǎng)”策略的時(shí)間,強(qiáng)制內(nèi)部標(biāo)準(zhǔn)/協(xié)定,并促進(jìn)開(kāi)發(fā)過(guò)程。

            Microsoft 認(rèn)識(shí)到這一需要后提供了一個(gè)功能豐富、帶有下一代開(kāi)發(fā)平臺(tái) Visual Studio 2005 Team System (VSTS) 的代碼生成引擎。本文提供針對(duì)單元測(cè)試代碼生成的循序漸進(jìn)的指導(dǎo),并深入探討如何在用例中使用。

            返回頁(yè)首

            重新思考單元測(cè)試

            請(qǐng)考慮以下情況:您負(fù)責(zé)為公司生成下一代系統(tǒng),同時(shí)您是較大的開(kāi)發(fā)團(tuán)隊(duì)中的一員。您是 UI 開(kāi)發(fā)人員,負(fù)責(zé)盡可能多地創(chuàng)建 Microsoft ASP.NET/Microsoft WinForms。您依賴“中間層”團(tuán)隊(duì)完成其中間層組件 — 這些組件用于執(zhí)行數(shù)據(jù)庫(kù) CRUD (Create-Retrieve-Update-Delete) 以及與該系統(tǒng)中每個(gè)實(shí)體相關(guān)的業(yè)務(wù)規(guī)則。

            經(jīng)過(guò)幾周的 UI 開(kāi)發(fā),您完成了窗體并且收到了中間層開(kāi)發(fā)人員打算向您提交其類(lèi)庫(kù)的消息。表 1 提供一段對(duì)話示例,說(shuō)明我們大多數(shù)人在開(kāi)發(fā)過(guò)程中都會(huì)遇到的一些事情。

            表 1. UI 開(kāi)發(fā)人員和中間層開(kāi)發(fā)人員間的示例對(duì)話

            中間層:

            “這些對(duì)象隨時(shí)供您使用 — 為此,只需獲取 OurSystemBL.dll 的最新版本。”

            UI

            “謝謝。您有供我們查看文檔嗎?”

            中間層:

            “哈哈!是的,當(dāng)然有!我們花了很多時(shí)間編寫(xiě)它!請(qǐng)查看 Design Document — 噢,請(qǐng)等一等,它還沒(méi)有完成……(不久之后即可完成!)”

            UI

            “您使用 XML 文檔了嗎?”

            中間層:

            “在構(gòu)造函數(shù)中,但許多方法都不使用。”

            UI

            “顯示如何創(chuàng)建、執(zhí)行并刪除對(duì)象的示例代碼,怎么樣?”

            中間層:

            “我已經(jīng)附加了一個(gè)示例 WinForms 應(yīng)用程序(從我的工作區(qū)),它應(yīng)該能夠提供一些您所需的內(nèi)容……,雖然它不在 Microsoft Visual SourceSafe 中。”

            在考慮如何進(jìn)行這樣有趣的 項(xiàng)目之后,您打定了主意,決定檢驗(yàn)中間層的單元測(cè)試套件。在深入鉆研該代碼之后,您注意到該窗體有兩個(gè)未標(biāo)記的文本框,以及三個(gè)標(biāo)記為 button1button2button3 的按鈕(幸運(yùn)的話,它們將排列在窗體上)。接下來(lái),在查看與這些按鈕相關(guān)的事件之后,您認(rèn)識(shí)到這些代碼都未經(jīng)注釋,并且數(shù)據(jù)變量都被命名為 x、y、z。如果幸運(yùn),您還會(huì)注意到 button1button2 執(zhí)行該對(duì)象的 Save() 方法,而 button3 執(zhí)行 Delete() 方法。執(zhí)行時(shí),您會(huì)接收到很多 System.Exception 錯(cuò)誤,這是因?yàn)檫z漏了很多配置設(shè)置。

            這顯然是一個(gè)特例,我希望多數(shù)開(kāi)發(fā)團(tuán)隊(duì)不要進(jìn)行這一試驗(yàn),下面讓我們看一下該方案中“單元測(cè)試”遇到的問(wèn)題:

            • 這種形式的單元測(cè)試代碼不是結(jié)構(gòu)化的:代碼充斥到按鈕單擊事件中并且難以編譯。

            • 這種形式的單元測(cè)試代碼記錄得不太好。

            • 這種形式的單元測(cè)試并不基于“已知”為好或壞的數(shù)據(jù) — 它完全依賴于輸入到那些未標(biāo)記的文本框的內(nèi)容。

              • 單元測(cè)試代碼不能自動(dòng)重復(fù),它基于輸入的代碼。

              • 單元測(cè)試代碼覆蓋是未知的 — 用數(shù)據(jù)指示實(shí)際測(cè)試的代碼量。

            • 實(shí)現(xiàn)的詳細(xì)信息不易于在團(tuán)隊(duì)成員間進(jìn)行傳播。

            返回頁(yè)首

            輸入自動(dòng)化單元測(cè)試

            xUnit 框架在 1998 年作為 eXtreme 編程的核心概念引入。它提出了一個(gè)有效的機(jī)制,有助于開(kāi)發(fā)人員將結(jié)構(gòu)化、有效且自動(dòng)的單元測(cè)試添加常規(guī)開(kāi)發(fā)活動(dòng)中。從那以后,該框架演化為針對(duì)自動(dòng)化單元測(cè)試框架的實(shí)際標(biāo)準(zhǔn)。

            創(chuàng)建自動(dòng)化單元測(cè)試的用例

            簡(jiǎn)單說(shuō),自動(dòng)化單元測(cè)試是:

            • 結(jié)構(gòu)化的。

            • 自行記錄的。

            • 自動(dòng)且可重復(fù)的。

            • 基于已知數(shù)據(jù)。

            • 旨在測(cè)試積極和消極操作。

            • 非常適合跨不同計(jì)算機(jī)的測(cè)試實(shí)現(xiàn)。

            • 配置、實(shí)現(xiàn)和執(zhí)行的示例。

            xUnit 框架元素

            表 2 分析 xUnit 框架以及對(duì)應(yīng)于 Visual Studio 2005 Team System 的 Unit Testing Framework 等價(jià)物的基本概念。

            表 2. 相應(yīng)的 xUnit 框架和 VSTS Unit Testing Framework 概念

            xUnit 框架概念

            VS 2005 等價(jià)物(參見(jiàn)下面的屬性)

            描述

            測(cè)試

            TestMethod

            簡(jiǎn)單說(shuō),這些是您的測(cè)試。測(cè)試預(yù)期結(jié)果的邏輯,并報(bào)告未取得結(jié)果(如果有)。請(qǐng)將它看作您的“方法”。

            測(cè)試裝置

            TestClass

            針對(duì)大量測(cè)試的一個(gè)邏輯分組。請(qǐng)將它看作您的“類(lèi)”。

            測(cè)試套件

            測(cè)試列表 **

            針對(duì)大量測(cè)試裝置的一個(gè)邏輯分組。請(qǐng)將它看作您的“類(lèi)庫(kù)”。

            注不需要一個(gè)屬性。

            測(cè)試運(yùn)行器

            VS 2005 VSTS Unit Testing Framework

            GUI/Console 應(yīng)用程序負(fù)責(zé)發(fā)現(xiàn)、執(zhí)行和報(bào)告測(cè)試結(jié)果。Visual Studio 2005 Team System 將作為本文的測(cè)試運(yùn)行器。

            測(cè)試裝置示例

            請(qǐng)考慮以下針對(duì) BankAccount 類(lèi)的類(lèi)關(guān)系圖,以及一個(gè)示例測(cè)試裝置 (BankAccountTests.cs)。

            1. BankAccount 類(lèi)

            示例測(cè)試裝置: BankAccountTests.cs
            using BankAccountDemo.Business;
            using Microsoft.VisualStudio.QualityTools.UnitTesting.Framework;
            namespace BankAccountDemo.Business.Tests
            {
                [TestClass()]
                public class BankAccountTest
                {
                    [TestInitialize()]
                    public void Initialize()    {
                    }
                    [TestCleanup()]
                    public void Cleanup()   {
                    }
                    [TestMethod()]
                    public void ConstructorTest()   {
                        float currentBalance = 500; 
                        BankAccount target = new BankAccount(currentBalance);
                        Assert.AreEqual(currentBalance, target.CurrentBalance, 
                            "Balances are not equal upon creation");
                    }
                    [TestMethod()]
                    public void DepositMoneyTest()  {
                        float currentBalance = 500; 
                        BankAccount target = new BankAccount(currentBalance);
                        float depositAmount = 10; 
                        target.DepositMoney(depositAmount);
                        Assert.IsTrue( (currentBalance + depositAmount) >  
                                        target.CurrentBalance, 
                           "Deposit not applied correctly");
                    }
                    [TestMethod()]
                    public void MakePaymentTest()   {
                        float currentBalance = 500; 
                        BankAccount target = new BankAccount(currentBalance);
                        float paymentAmount = 250; 
                        target.MakePayment(paymentAmount);
                        Assert.IsTrue(currentBalance - paymentAmount == 
                          target.CurrentBalance, 
                            "Payment not applied correctly");
                    }
                }
            }
            
            主單元測(cè)試概念 == 斷言

            用于該形式單元測(cè)試的主要概念是,自動(dòng)化單元測(cè)試是基于“斷言”的,即可定義為“事實(shí)或您相信為事實(shí)的內(nèi)容”。從邏輯角度看,請(qǐng)考慮該語(yǔ)句“when I do {x}, I expect {y} as a result”。

            這可以輕松地翻譯為代碼,方法是使用 Microsoft.VisualStudio.QualityTools.UnitTesting.Framework 命名空間中可用的三個(gè)“斷言”類(lèi)中的任一個(gè):AssertStringAssertCollectionAssert。主類(lèi) Assert 提供用于測(cè)試基礎(chǔ)條件語(yǔ)句的斷言。StringAssert 類(lèi)自定義了在使用字符串變量時(shí)有用的斷言。同樣,CollectionAssert 類(lèi)包括在使用對(duì)象集合時(shí)有用的斷言方法。

            表 3 顯示可用于當(dāng)前版本 Unit Testing Framework 的斷言。

            表 3. VSTS Unit Testing Framework 斷言

            斷言類(lèi)

            StringAssert 類(lèi)

            CollectionAssert 類(lèi)

            AreEqual() 
            AreNotEqual() 
            AreNotSame() 
            AreSame() 
            EqualsTests() 
            Fail() 
            GetHashCodeTests() 
            Inconclusive() 
            IsFalse() 
            IsInstanceOfType() 
            IsNotInstanceOfType() 
            IsNotNull() 
            IsNull() 
            IsTrue()
            
            Contains() 
            DoesNotMatch() 
            EndsWith() 
            Matches() 
            StartsWith()
            
            AllItemsAreInstancesOfType() 
            AllItemsAreNotNull() 
            AllItemsAreUnique() 
            AreEqual() 
            AreEquivalent() 
            AreNotEqual()
            AreNotEquivalent()
            Contains()
            DoesNotContain() 
            IsNotSubsetOf()
            IsSubsetOf()
            
            這些自動(dòng)化單元測(cè)試用什么運(yùn)行?

            正如前面提到的,xUnit 框架將“測(cè)試運(yùn)行器”的概念定義為應(yīng)用程序負(fù)責(zé):(a) 執(zhí)行單元測(cè)試;(b) 報(bào)告測(cè)試結(jié)果。對(duì)于本文,包含 Visual Studio 2005 Team System (VSTS) 的 Unit Testing 引擎作為我們的“測(cè)試運(yùn)行器”。圖 2 表示 BankAccountTests.cs 類(lèi)的執(zhí)行結(jié)果。

            2. 測(cè)試結(jié)果窗格:?jiǎn)卧獪y(cè)試執(zhí)行結(jié)果

            Microsoft Visual Studio 2005 使用源項(xiàng)目的代碼模型動(dòng)態(tài)填充該視圖。它基于該源代碼中的自定義屬性動(dòng)態(tài)發(fā)現(xiàn)有關(guān)該測(cè)試套件的信息。表 4 表示最常見(jiàn)的單元測(cè)試屬性(以及執(zhí)行的次序)。

            表 4. 常見(jiàn)單元測(cè)試屬性

            屬性

            描述

            TestClass()

            該屬性表示一個(gè)測(cè)試裝置。

            TestMethod()

            該屬性表示一個(gè)測(cè)試用例。

            AssemblyInitialize()

            在執(zhí)行為執(zhí)行選擇的第一個(gè) TestClass() 中的第一個(gè) TestMethod() 之前,執(zhí)行帶有該屬性的方法。

            ClassInitialize()

            帶有該屬性的方法在執(zhí)行第一個(gè)測(cè)試之前調(diào)用。

            TestInitialize()

            帶有該屬性的方法在執(zhí)行每個(gè) TestMethod() 之前調(diào)用。

            TestCleanup()

            帶有該屬性的方法在執(zhí)行每個(gè) TestMethod() 之后調(diào)用。

            ClassCleanup()

            帶有該屬性的方法在執(zhí)行 ALL 測(cè)試之后調(diào)用。

            AssemblyCleanup()

            在執(zhí)行為執(zhí)行選擇的第一個(gè) TestClass() 中的第一個(gè) TestMethod() 之后,執(zhí)行帶有該屬性的方法。

            Description()

            提供關(guān)于給定 TestMethod() 的描述。

            Ignore()

            由于某種原因忽略 TestMethod()TestClass()

            ExpectedException()

            當(dāng)測(cè)試特定異常時(shí),如果使用該屬性指定的異常不是從實(shí)現(xiàn)代碼引發(fā),則測(cè)試不會(huì)失敗。

            我編寫(xiě)什么類(lèi)型的測(cè)試?

            一個(gè)方法及其相關(guān)測(cè)試之間很難有一對(duì)一關(guān)系。編寫(xiě)自動(dòng)化單元測(cè)試需要開(kāi)發(fā)人員“進(jìn)行全面思考”,并了解關(guān)于對(duì)象的所有內(nèi)容 — 它將如何消耗、使用、處理,以及在任何情況下如何起到積極、消極、非決定性作用。

            例如,請(qǐng)考慮一個(gè)用于針對(duì)數(shù)據(jù)庫(kù)中 Customer 項(xiàng)執(zhí)行 CRUD(創(chuàng)建、檢索、更新、刪除)功能的典型對(duì)象方法。對(duì)于該對(duì)象的 Load() 方法,要針對(duì)以下方案編寫(xiě)測(cè)試:

            • 構(gòu)造函數(shù)測(cè)試 — 確保對(duì)象正確加載,帶有正確的信息。

            • PositiveLoadScalarTest — 測(cè)試數(shù)據(jù)庫(kù)中一個(gè) Customer 的成功加載。

            • NegativeLoadScalarTest — 測(cè)試一個(gè) Customer 的失敗加載,即該 Customer 不在數(shù)據(jù)庫(kù)中。

            • PositiveLoadTest — 基于已知數(shù)據(jù)測(cè)試 Customer 的成功加載。

            • NegativeLoadTest — 測(cè)試數(shù)據(jù)庫(kù)中不存在的 Customer 的失敗加載。

            • NegativeValidationTest — 確保驗(yàn)證邏輯正確工作。

            這些只是自動(dòng)化單元測(cè)試套件許多用法中的一部分。我曾經(jīng)聽(tīng)說(shuō)一個(gè)小團(tuán)隊(duì)使用單元測(cè)試查看針對(duì)其組件的已知安全攻擊。從宏觀的角度來(lái)看,單元測(cè)試應(yīng)該明確保證組件的正常使用。具有豐富的測(cè)試集將使團(tuán)隊(duì)確信您已經(jīng)準(zhǔn)確實(shí)現(xiàn)了既定的目標(biāo):編寫(xiě)有效的軟件。無(wú)論自信源自哪里 — 這就是您需要編寫(xiě)的測(cè)試。

            您測(cè)試什么?

            從本質(zhì)上看,這些自動(dòng)化單元測(cè)試非常低級(jí)。它們旨在測(cè)試下至構(gòu)造函數(shù)、方法調(diào)用的對(duì)象,甚至是對(duì)象上的屬性。

            關(guān)于“公共對(duì)私有”的主題在單元測(cè)試派系中引發(fā)了許多爭(zhēng)論。許多人認(rèn)為單元測(cè)試只應(yīng)該測(cè)試對(duì)象的公共接口。其他人認(rèn)為應(yīng)該測(cè)試每個(gè)調(diào)用 — 包括內(nèi)部私有方法。VSTS 支持兩個(gè)單元測(cè)試級(jí)別。VSTS 通過(guò)使用私有訪問(wèn)器或包裝類(lèi)支持私有測(cè)試,后者提供基于“私有”方法和屬性生成單元測(cè)試的功能。

            返回頁(yè)首

            為什么生成代碼?

            閱讀上面的列表后,您可能會(huì)想起前面項(xiàng)目的單個(gè)對(duì)象,并思考:“如果我用“這些”對(duì)象進(jìn)行該操作,就需要編寫(xiě)大量代碼!”請(qǐng)考慮開(kāi)發(fā)人員仍編寫(xiě)“單元測(cè)試” 代碼的事實(shí) — 只在不同的窗體(例如,前面提到的 WinForms 示例)上進(jìn)行。此外,具有可自行記錄、可重用的實(shí)現(xiàn)示例帶來(lái)的好處遠(yuǎn)大于生成更多代碼所帶來(lái)的麻煩。最后,在單元測(cè)試中設(shè)計(jì)更多的環(huán)節(jié)已證明可以減少質(zhì)量保證環(huán)節(jié)中的故障。

            正如前面所提到的,代碼生成是“軟件創(chuàng)建軟件”的過(guò)程。基于可重復(fù)的過(guò)程創(chuàng)建代碼是理想的。例如,一些使用代碼生成的較好示例包括:腳本數(shù)據(jù)、創(chuàng)建表示實(shí)體及其在儲(chǔ)存庫(kù)(數(shù)據(jù)庫(kù) CRUD)中存在的對(duì)象,或者創(chuàng)建適用于數(shù)據(jù)維護(hù)的 UI 控件。使用代碼生成的好處包括:

            • 節(jié)省時(shí)間 — 為什么花幾小時(shí)/天/周創(chuàng)建一些在幾秒/分鐘內(nèi)就可以創(chuàng)建的內(nèi)容?

            • 強(qiáng)制標(biāo)準(zhǔn) / 約定 — 對(duì)于強(qiáng)制您的標(biāo)準(zhǔn)和命名約定而言,沒(méi)有什么比消除開(kāi)發(fā)中的人員因素并依賴基于“您的”規(guī)則的可重復(fù)過(guò)程更好的了。

            • 測(cè)試私有方法的功能 — 正如本文前面提到的,Unit Testing Framework 提供使用“私有訪問(wèn)器”類(lèi)測(cè)試私有方法的功能。該代碼生成引擎創(chuàng)建與這些訪問(wèn)器類(lèi)相關(guān)的所有“基礎(chǔ)代碼”。

            • 獲取現(xiàn)有組件的信息 — 搜索另一個(gè)開(kāi)發(fā)人員的組件嗎?基于這些組件生成代碼可能提供關(guān)于該實(shí)現(xiàn)以及該對(duì)象接口的簡(jiǎn)明示例。此外,進(jìn)行設(shè)計(jì)并在編碼之前“清除”其對(duì)象的公共接口(例如,通過(guò)使用 VS 2005 類(lèi)設(shè)計(jì)器)的開(kāi)發(fā)人員將極大地受益于代碼生成引擎。

            正如您所預(yù)期的,自動(dòng)化單元測(cè)試屬于“優(yōu)秀代碼生成候選者”。在現(xiàn)有組件中指出一些內(nèi)容并針對(duì)這些自動(dòng)單元測(cè)試生成初始代碼難道不是很理想嗎?而且不只是保留單元測(cè)試框架,還會(huì)圍繞對(duì)象的公共接口生成實(shí)現(xiàn)示例嗎?將來(lái)的 Visual Studio 2005 Team System 用戶將擁有該功能以及更多功能!

            返回頁(yè)首

            讓我們生成一些代碼吧!

            本例中,我們將生成本文前面提到的 BankAccount 類(lèi)的代碼。本文的這一部分旨在為您介紹代碼生成過(guò)程,并重點(diǎn)介紹所提供的功能以及從 VSTS 使用 Unit Testing 引擎的好處。

            第 1 步:創(chuàng)建您的實(shí)現(xiàn)代碼

            首先,我們創(chuàng)建一個(gè)將用作應(yīng)用程序的業(yè)務(wù)層的類(lèi)庫(kù)項(xiàng)目。

            要在 VS 2005 中創(chuàng)建該庫(kù):

            1. 啟動(dòng) Visual Studio 2005 Beta 2。

            2. 單擊 File | New | Project

            3. 選擇您選定的語(yǔ)言 Windows,并選擇 Class Library 項(xiàng)目模板。

            4. NameSolution Name 設(shè)置為 BankAccountDemo.Business,選擇一個(gè)位置,并單擊 OK 來(lái)創(chuàng)建該類(lèi)庫(kù)。

            VS 2005 創(chuàng)建該類(lèi)后,下一個(gè)任務(wù)就是創(chuàng)建針對(duì)您的項(xiàng)目設(shè)計(jì)的 BankAccount 類(lèi)。為此,需要執(zhí)行以下操作:

            1. 在解決方案資源管理器中單擊右鍵,并單擊 Delete,從項(xiàng)目中移除該文件并將其從硬盤(pán)中刪除。

            2. 右鍵單擊 BankAccountDemo.Business 項(xiàng)目,然后單擊 Add,之后單擊 Class

            3. 選擇文件名 BankAccount.cs,并單擊 Add 創(chuàng)建類(lèi)文件。

            4. 針對(duì) BankAccount.cs 文件對(duì)代碼進(jìn)行以下更改。

            using System;
            using System.Collections.Generic;
            using System.Text;
            
            namespace BankAccountDemo.Business
            {
                public class BankAccount
                {
                    // Properties
                    private float _currentBalance;
            
                    public float CurrentBalance
                    {
                        get { return _currentBalance; }
                    }
            
                    // Constructors
                    public BankAccount(float initialBalance)
                    {
                        this._currentBalance = initialBalance;
                    }
            
                    // Methods
                    public void DepositMoney(float depositAmount)
                    {
                        this._currentBalance += depositAmount;
                    }
            
                    public void MakePayment(float paymentAmount)
                    {
                        this._currentBalance -= paymentAmount;
                    }
                }
            
            }
            
            第 2 步:生成您的初始單元測(cè)試代碼

            由于 Unit Testing 引擎內(nèi)置于 Visual Studio 2005 Team System,因此生成代碼比以前更容易。除了生成單元測(cè)試結(jié)構(gòu)之外,它將生成特定于實(shí)例的信息,例如,對(duì)象創(chuàng)建、類(lèi)型化參數(shù)和方法執(zhí)行。

            VS 2005 提供在任何類(lèi)結(jié)構(gòu)級(jí)別生成單元測(cè)試代碼的功能,這些級(jí)別包括命名空間、類(lèi)、方法、屬性、構(gòu)造函數(shù),等等。可通過(guò)右鍵單擊這些代碼元素并單擊 Generate test(s)(圖 3)進(jìn)行此操作。

            3. Generate test(s) 方法

            因此,要開(kāi)始代碼生成過(guò)程,請(qǐng)執(zhí)行以下步驟:

            • 右鍵單擊該類(lèi)名 BankAccount 并單擊 Create Tests

            現(xiàn)在,應(yīng)該為您提供 Generate Unit Tests 對(duì)話框(如圖 4 所示)。該對(duì)話框及其組件提供對(duì)該過(guò)程中生成的代碼進(jìn)行自定義的功能。讓我們看一下所有這些元素。

            4. 生成 Unit Tests 對(duì)話框

            Current selection: 樹(shù)視圖允許導(dǎo)航自定義類(lèi)及其元素。VS 2005 使用反射填充該樹(shù)視圖,并在右鍵單擊以及單擊 Create Tests 的位置自動(dòng)選擇組件。圖 3 中,由于我在類(lèi)級(jí)別進(jìn)行了此操作,因此該對(duì)話框自動(dòng)選擇用于代碼生成的所有類(lèi)元素。如果選擇在單個(gè)級(jí)別(即,構(gòu)造函數(shù)、屬性或方法)進(jìn)行生成,則只選擇那些元素。

            Filter 選項(xiàng)(位于右上角)提供修改樹(shù)視圖(圖 5)中所示結(jié)果的功能,包括顯示非公共項(xiàng)、基類(lèi)型以及“只屬于我的代碼”。如果使用的是大型解決方案,或者感覺(jué)顯示私有的內(nèi)部結(jié)構(gòu)會(huì)弄亂選擇窗口,那么這對(duì)您很有益處。

            5. 篩選選擇結(jié)果

            下一個(gè)是 Output project 對(duì)話框(位于 Current selection: 樹(shù)視圖下)。該列表框允許您針對(duì)生成的測(cè)試裝置選擇目的項(xiàng)目(圖 6)。如果您的解決方案包含以前創(chuàng)建的測(cè)試項(xiàng)目,則將包含該測(cè)試項(xiàng)目以供選擇。由于這是我們首次訪問(wèn)該對(duì)話框,因此可以選擇 Create a new Test Project 選項(xiàng)。

            6. 輸出項(xiàng)目選擇

            要繼續(xù)我們的過(guò)程,請(qǐng)執(zhí)行以下操作:

            • 基于您選擇的語(yǔ)言選擇 Create a new {0} Test Project

            最后,該對(duì)話框提供通過(guò) Settings 按鈕(位于左下角)自定義代碼生成過(guò)程的功能。單擊該按鈕將加載 Test Generation Settings 對(duì)話框,如圖 7 所示。

            7. Test Generation Settings 對(duì)話框

            該對(duì)話框允許您進(jìn)行以下更改:

            • 更改命名約定,它們用于生成針對(duì)文件、類(lèi)(測(cè)試裝置)和方法(測(cè)試)的名稱。

            • 打開(kāi)/關(guān)閉使所有測(cè)試結(jié)果在默認(rèn)情況下為 Inconclusive 的功能。選擇該選項(xiàng)將在每個(gè)生成的 Test() 方法中包含以下占位符語(yǔ)句。

              Assert.Inconclusive("TODO: Implement code to verify target");
              
            • 打開(kāi)/關(guān)閉啟用生成警告的功能 — 即,如果在代碼生成過(guò)程中出現(xiàn)任何警告,都要進(jìn)行報(bào)告。

            • 在全局范圍內(nèi)限制所有類(lèi)型。該設(shè)置通知代碼生成引擎將一個(gè)全局限定符(在 Microsoft Visual C# 2005 中是 global::)添加到變量聲明中。當(dāng)在多個(gè)命名空間中具有名稱相似的對(duì)象時(shí),請(qǐng)使用該設(shè)置。否則,代碼生成引擎將創(chuàng)建邏輯來(lái)創(chuàng)建該對(duì)象,但是編譯器不能確定創(chuàng)建哪個(gè)類(lèi),因此會(huì)產(chǎn)生錯(cuò)誤。

            • 啟用/禁用針對(duì)已具有測(cè)試的項(xiàng)生成測(cè)試的功能。下面我們將討論關(guān)于后續(xù)代碼生成嘗試的主題。

            • 啟用/禁用文檔注釋。這允許您在使用每個(gè) Test() 方法時(shí)禁用 XML 文檔的創(chuàng)建

            要完成我們的配置并生成單元測(cè)試代碼(以及更多),請(qǐng)執(zhí)行以下操作:

            1. 單擊 OK 按鈕開(kāi)始代碼生成過(guò)程。

            2. 輸入名稱 BankAccountDemo.Business.Test 作為新項(xiàng)目名,并單擊 Create 按鈕完成該過(guò)程。

            VS 2005 將顯示一個(gè)進(jìn)度欄,提供代碼生成過(guò)程中的狀態(tài)。該過(guò)程將在幾秒鐘內(nèi)完成,您可以看到一個(gè)名為 BankAccountTest.cs 的類(lèi)。

            返回頁(yè)首

            生成了什么?

            在我們對(duì)該測(cè)試裝置進(jìn)行特別查看之前,讓我們看一下在代碼生成過(guò)程中創(chuàng)建了什么。

            首先,它創(chuàng)建了 Test Class Library 項(xiàng)目 BankAccountDemo.Business.Test。請(qǐng)注意該項(xiàng)目如何包含對(duì)實(shí)現(xiàn)類(lèi) BankAccountDemo.Business(您從其中生成代碼)和 Microsoft.VisualStudio.QualityTools.UnitTestFramework 類(lèi)庫(kù)的引用。在查看該類(lèi)的內(nèi)容時(shí),您將注意到以下文件:

            • AuthoringTests.txt — 這是一些信息性的內(nèi)容,定義如何使用單元測(cè)試(打開(kāi)、查看、運(yùn)行、查看結(jié)果、更改測(cè)試的運(yùn)行方式),以及 VSTS 中包含的不同測(cè)試類(lèi)型的定義。

            • ManualTest1.mht — 這是 VSTS 中使用的手動(dòng)測(cè)試套件,用于執(zhí)行測(cè)試并報(bào)告結(jié)果。手動(dòng)測(cè)試是 VSTS 支持的一個(gè)附加測(cè)試類(lèi)型。有關(guān)更多信息,請(qǐng)參閱 MSDN 資源庫(kù)的“手動(dòng)測(cè)試”主題。

            • UnitTest1.cs — 這是一個(gè)引用類(lèi),它只提供一個(gè)基單元測(cè)試(包括 TestClass、TestInitialize、TestCleanup 和 TestMethod 的定義)。

            • BankAccountTest.cs — 這是特定于程序集生成的單元測(cè)試代碼。讓我們仔細(xì)看看該代碼,它是代碼生成過(guò)程中最重要的部分。

            由 Unit Testing 引擎生成的類(lèi)包括以下組件:

            • Using/imports 語(yǔ)句,用于引用的程序集。

            • TestClass() 定義,用于包含該測(cè)試的類(lèi) (BankAccountTestFixture)。

            • 一個(gè)私有訪問(wèn)器和用于 TestContext 的公共屬性。它由單元測(cè)試運(yùn)行器(即 VSTS Unit Test Framework)使用,以便提供關(guān)于當(dāng)前測(cè)試運(yùn)行的信息以及用于該運(yùn)行的功能。

            • TestInitialize()TestCleanup() 方法。這些方法常用于獲取和釋放測(cè)試所需的任何對(duì)象。

            • TestMethod(),用于每個(gè)選定的方法。

            讓我們仔細(xì)看一下 DepositMoneyTest(),它負(fù)責(zé)確保當(dāng)前的平衡能反映原始數(shù)量與累計(jì)數(shù)量的總和。

            /// 
            ///A test case for DepositMoney (float)
            ///
            [TestMethod()]
            public void DepositMoneyTest()
            {
            float initialBalance = 0; // TODO: Initialize to an appropriate value
            BankAccount target = new BankAccount(initialBalance);
            float depositAmt = 0; // TODO: Initialize to an appropriate value
            target.DepositMoney(depositAmt);
            Assert.Inconclusive("A method that does not return a value" +
               "cannot be verified.");
            }
            

            請(qǐng)注意該生成引擎除創(chuàng)建一個(gè) stub TestMethod() 對(duì)象外,是如何進(jìn)行其他操作的。它創(chuàng)建了適用于接口的示例單元測(cè)試,包括:

            • BankAccount 對(duì)象的分配和結(jié)構(gòu)(測(cè)試的對(duì)象主題)

            • 本地變量的創(chuàng)建和默認(rèn)分配,這些變量表示作為該測(cè)試主題的方法/構(gòu)造函數(shù)所需的參數(shù)。

              • TODO 注釋,提醒開(kāi)發(fā)人員適當(dāng)?shù)胤峙鋮?shù)變量。

            • 如果測(cè)試基于一個(gè)源對(duì)象方法調(diào)用,則生成的代碼將包含對(duì)該方法(帶有用于這些參數(shù)的局部變量)的調(diào)用。

            • 初始 Assert() 方法調(diào)用,基于該方法的返回值。

            • Assert.Inconclusive() 方法調(diào)用,作為完成測(cè)試代碼的提示程序。非確定性測(cè)試將在 Test Results 對(duì)話框中顯示為失敗。

            返回頁(yè)首

            生成后:我現(xiàn)在需要做什么?

            考慮要完成相同的操作可以不必做哪些事情,則通常可以認(rèn)識(shí)到代碼生成的好處。在我們的示例中,我們不必:

            • 創(chuàng)建單元測(cè)試項(xiàng)目。

            • 設(shè)置項(xiàng)目引用。

            • 添加適當(dāng)?shù)臏y(cè)試類(lèi)(一個(gè)或多個(gè))。

            • 生成主干 Unit Test Framework 類(lèi)和屬性。

            • 創(chuàng)建單個(gè)測(cè)試方法。

            • 創(chuàng)建特定于接口的邏輯。

            由于代碼生成過(guò)程創(chuàng)建了特定于對(duì)象接口的示例單元測(cè)試,因此我們接近于初始測(cè)試的完成階段了。通常情況下,只需“填充空白”并完成斷言(一個(gè)或多個(gè)),方法是將“已知的數(shù)據(jù)值”分配給屬性變量并創(chuàng)建適當(dāng)?shù)?Assert() 方法。顯然,這不是針對(duì)所有測(cè)試的示例,特別是對(duì)具有多個(gè)斷言的復(fù)雜測(cè)試而言。

            只需幾秒鐘的時(shí)間(使用相對(duì)較少的擊鍵),您就能夠?qū)⑸傻膯卧獪y(cè)試代碼轉(zhuǎn)換為這些實(shí)際的測(cè)試。

            例如,請(qǐng)考慮我們以如下方式開(kāi)始。

            [TestMethod()]
            public void DepositMoneyTest()
            {
            float initialBalance = 0; // TODO: Initialize to an appropriate value
            BankAccount target = new BankAccount(initialBalance);
            float depositAmt = 0; // TODO: Initialize to an appropriate value
            target.DepositMoney(depositAmt);
            Assert.Inconclusive("A method that does not return a value " + 
              "cannot be verified.");
            }
            

            我們能夠完成相對(duì)容易且具有有限擊鍵的測(cè)試(更改部分用黑體表示)。

            [TestMethod()]
            public void DepositMoneyTest()  {
            float currentBalance = 500; 
            BankAccount target = new BankAccount(currentBalance);
            float depositAmt = 10; 
            target.DepositMoney(depositAmt);
            Assert.AreEqual(currentBalance + depositAmt, target.CurrentBalance, 
                              "Deposit Test: Deposit not applied correctly");
            }
            

            返回頁(yè)首

            重新生成單元測(cè)試代碼

            好消息是,代碼生成過(guò)程不會(huì)讓您重寫(xiě)以前生成(和修改)的單元測(cè)試。使用 Visual Studio 2005 Team System 的 Beta 2 版本,代碼生成選項(xiàng)提供一個(gè)啟用/禁用創(chuàng)建已存在測(cè)試的復(fù)選框。如果選擇它,而且該過(guò)程找到了一個(gè)具有相同名稱的現(xiàn)有測(cè)試,則該過(guò)程將忽略該測(cè)試方法,并創(chuàng)建后續(xù)測(cè)試,從而將一個(gè)數(shù)字附加到該方法名的末尾。這通常在對(duì)象中使用重載的方法或構(gòu)造函數(shù)時(shí)發(fā)生,或者當(dāng)單擊 Generate 按鈕而不取消選定現(xiàn)有測(cè)試時(shí)發(fā)生。

            返回頁(yè)首

            自動(dòng)化單元測(cè)試建議

            雖然本節(jié)可以獨(dú)立成文,但這里只是一些您在創(chuàng)建單元測(cè)試時(shí)可以采納的基本建議。

            • 設(shè)計(jì)彼此獨(dú)立的單元測(cè)試,其中它們可以獨(dú)立運(yùn)行(由于可以通過(guò)測(cè)試 UI 隨意選擇或取消選定它們)。

            • 不要只進(jìn)行正面測(cè)試。請(qǐng)確保代碼能夠響應(yīng)任何方案,包括發(fā)生意外時(shí)(資源不可用,數(shù)據(jù)庫(kù)只讀等)。

            • 把自己當(dāng)作一個(gè) QA 人員,想象成一個(gè)測(cè)試人員,而不僅僅是一個(gè)開(kāi)發(fā)人員。您花在設(shè)計(jì)單元測(cè)試上的時(shí)間將有助于減少日后解決故障所用的時(shí)間。請(qǐng)注意對(duì)象的幾個(gè)小細(xì)節(jié):數(shù)據(jù)如何在對(duì)象之間傳輸?誰(shuí)使用它們?銷(xiāo)毀對(duì)象容易嗎?如果我“進(jìn)行此操作”,將會(huì)發(fā)生什么?

            • 跳出您自己的思維模式。盡可能多地對(duì)測(cè)試進(jìn)行頭腦風(fēng)暴。當(dāng)您完成時(shí),回頭查看您可能漏掉的內(nèi)容。來(lái)自團(tuán)隊(duì)成員的請(qǐng)求反饋 — 例如,他們創(chuàng)建了什么其他類(lèi)型的測(cè)試?其他人可能提供一個(gè)對(duì)熟悉自己代碼的開(kāi)發(fā)人員而言非常困難的觀點(diǎn)。

            • 代碼覆蓋。使用 VSTS 代碼覆蓋規(guī)范提供有關(guān)每個(gè)測(cè)試運(yùn)行中實(shí)際執(zhí)行多少代碼的信息(代碼的行數(shù),占所有代碼的百分比)。如果編碼完成,并且通過(guò)了所有測(cè)試,但代碼覆蓋顯示只執(zhí)行了該邏輯的一小部分,那么您的測(cè)試真的成功了嗎?高代碼覆蓋不一定意味著您具有一個(gè)完整的“測(cè)試”集,而未覆蓋的代碼通常非常適用于一個(gè)新的測(cè)試用例。

            • 當(dāng)生成單元測(cè)試時(shí),要幫助其他人了解您的代碼:

              • 使用一個(gè)項(xiàng)目結(jié)構(gòu),該結(jié)構(gòu)映射所測(cè)試程序集的結(jié)構(gòu)。

                每個(gè)程序集有一個(gè)相關(guān)的測(cè)試程序集。

                每個(gè)類(lèi)有一個(gè)相關(guān)的測(cè)試類(lèi)。

                在各自的測(cè)試方法中包含每個(gè)方法名(即,Load() 將有 PositiveLoadTest()NegativeLoadTest()PositiveScalarLoadTest() 等的測(cè)試方法)。

              • 使用一致的命名協(xié)定,包括對(duì)象的屬性和方法名。

            • 此外,當(dāng)其他所有測(cè)試都失敗時(shí),請(qǐng)進(jìn)行調(diào)試。自動(dòng)化單元測(cè)試應(yīng)該有助于減少您用在調(diào)試器上的時(shí)間。但是,如果測(cè)試結(jié)果和代碼覆蓋無(wú)法提供測(cè)試失敗的原因,那么您大可不必?fù)?dān)心調(diào)試單元測(cè)試。從 Beta 2 版的 Visual Studio 2005 Team System 開(kāi)始,開(kāi)發(fā)人員可以使用 Test Manager 中的 Debug checked tests 選項(xiàng)調(diào)試他們的單元測(cè)試程序集。

            返回頁(yè)首

            小結(jié)

            自動(dòng)化單元測(cè)試為開(kāi)發(fā)環(huán)節(jié)提供了一個(gè)結(jié)構(gòu)化、自行紀(jì)錄、高度便攜且可重復(fù)的過(guò)程。如果在搜索現(xiàn)有程序集,或者如果開(kāi)發(fā)環(huán)境需要在開(kāi)始開(kāi)發(fā)之前進(jìn)行完整的設(shè)計(jì),則請(qǐng)考慮使用內(nèi)置到 Microsoft Visual Studio 2005 Team System 中的代碼生成引擎。Visual Studio 2005 Team System 的單元測(cè)試代碼生成功能可以為您節(jié)省寶貴的時(shí)間,而且有助于強(qiáng)制團(tuán)隊(duì)的開(kāi)發(fā)標(biāo)準(zhǔn)和約定。通過(guò)生成用于自動(dòng)化單元測(cè)試的基本內(nèi)容,包括生成帶有對(duì)象創(chuàng)建的測(cè)試方法、參數(shù)變量和基斷言類(lèi),您應(yīng)該能夠順利地在您的開(kāi)發(fā)方法論中采用自動(dòng)化單元測(cè)試。

            作者簡(jiǎn)介

            作為針對(duì) telligent 系統(tǒng)的專業(yè)服務(wù)主管,Scott Dockendorf 擅長(zhǎng)于用 .NET 提供高性能、可伸縮的應(yīng)用程序。Scott 熱衷于解決方案體系結(jié)構(gòu)、安全開(kāi)發(fā),他通過(guò)標(biāo)準(zhǔn)和已通過(guò)驗(yàn)證的方法論幫助企業(yè)采用推薦的實(shí)踐。Scott 是 .NET 社區(qū)的一個(gè)積極成員,他自愿作為 North Dallas .NET User Group 的程序主管。他還參加了面向本地 .NET 用戶組的會(huì)議,而且是 INETA's International Academic Committee for Texas 的活躍分子。您可以通過(guò)他的電子郵件 (scottd@telligent.com) 或網(wǎng)絡(luò)日記 (http://weblogs.asp.net/scottdockendorf) 與他聯(lián)系。

            轉(zhuǎn)到原英文頁(yè)面

            posted on 2008-10-09 18:09 FongLuo 閱讀(464) 評(píng)論(0)  編輯 收藏 引用


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


            <2008年10月>
            2829301234
            567891011
            12131415161718
            19202122232425
            2627282930311
            2345678

            導(dǎo)航

            常用鏈接

            留言簿

            隨筆分類(lèi)(11)

            隨筆檔案(79)

            文章檔案(1)

            收藏夾(38)

            學(xué)習(xí)網(wǎng)站

            一般網(wǎng)站

            最新隨筆

            搜索

            積分與排名

            最新評(píng)論

            閱讀排行榜

            久久精品亚洲乱码伦伦中文| 国产成人久久AV免费| 久久精品无码一区二区三区| 久久久久国产精品嫩草影院| 欧美精品福利视频一区二区三区久久久精品| 久久国产精品无码HDAV| 午夜天堂精品久久久久| 亚洲日本va中文字幕久久| 亚洲国产成人乱码精品女人久久久不卡 | 亚洲综合精品香蕉久久网97| 亚洲精品美女久久久久99| 久久久亚洲裙底偷窥综合| 久久久无码精品亚洲日韩蜜臀浪潮| 亚洲国产精品无码久久九九 | 人妻无码αv中文字幕久久琪琪布 人妻无码精品久久亚瑟影视 | 无码国产69精品久久久久网站| 久久人人爽人人爽人人片AV不| 久久婷婷五月综合成人D啪| 成人久久免费网站| 午夜精品久久久久久中宇| 久久丫精品国产亚洲av不卡| 精品久久久久久久久午夜福利| 久久久久久久97| 久久久久中文字幕| 久久久久亚洲AV无码专区桃色 | 亚洲乱码中文字幕久久孕妇黑人| 婷婷伊人久久大香线蕉AV| 久久99精品久久久久久动态图 | 亚洲国产综合久久天堂| 久久国产色av免费看| 99久久精品毛片免费播放| 国产成人精品综合久久久| 亚洲国产一成久久精品国产成人综合| 久久精品国产99国产精品导航| 久久99精品久久久久久| 色综合久久中文字幕综合网| 亚洲色欲久久久综合网东京热| 伊人久久免费视频| 精品国产乱码久久久久久呢 | 色婷婷综合久久久久中文字幕 | 久久精品国产亚洲AV大全|