使用 Visual Studio 2005 Team System 进行单元测试并生成用于 Unit Test Framework 的源代码...
Microsoft Visual Studio 2005 Team System Beta 2
Team Architect & Team Test Editions
Microsoft Visual C# 2005
摘要: Scott 詳細(xì)介紹自動(dòng)化單元測試的基本內(nèi)容,以及由 Microsoft Visual Studio 2005 Team System 提供的 Unit Test Framework 中包含的代碼生成引擎。
本頁內(nèi)容
| 簡介 | |
| 重新思考單元測試 | |
| 輸入自動(dòng)化單元測試 | |
| 為什么生成代碼? | |
| 讓我們生成一些代碼吧! | |
| 生成了什么? | |
| 生成后:我現(xiàn)在需要做什么? | |
| 重新生成單元測試代碼 | |
| 自動(dòng)化單元測試建議 | |
| 小結(jié) |
簡介
隨著業(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)者們在開發(fā)過程中(即,在實(shí)現(xiàn)之前)確保質(zhì)量。有一種方法可使開發(fā)人員減少進(jìn)入 QA 環(huán)節(jié)的故障數(shù)量,即,針對自定義代碼嚴(yán)格執(zhí)行自動(dòng)化單元測試。在開發(fā)過程中強(qiáng)制使用自動(dòng)化單元測試可為團(tuán)隊(duì)成員提供有關(guān)如何使用自定義代碼的示例(這些示例易于使用并自行記錄)。
使用結(jié)構(gòu)化、自動(dòng)化單元測試面臨的挑戰(zhàn)之一是完成這些任務(wù)所需的代碼總數(shù)。(測試代碼需要使用大量代碼!)代碼生成的概念(簡單定義為“創(chuàng)建軟件的軟件”)正隨著時(shí)間的快速推移而逐漸深入到團(tuán)隊(duì) IT 開發(fā)之中。有些人認(rèn)為代碼生成有助于縮短“推向市場”策略的時(shí)間,強(qiáng)制內(nèi)部標(biāo)準(zhǔn)/協(xié)定,并促進(jìn)開發(fā)過程。
Microsoft 認(rèn)識(shí)到這一需要后提供了一個(gè)功能豐富、帶有下一代開發(fā)平臺(tái) Visual Studio 2005 Team System (VSTS) 的代碼生成引擎。本文提供針對單元測試代碼生成的循序漸進(jìn)的指導(dǎo),并深入探討如何在用例中使用。
返回頁首重新思考單元測試
請考慮以下情況:您負(fù)責(zé)為公司生成下一代系統(tǒng),同時(shí)您是較大的開發(fā)團(tuán)隊(duì)中的一員。您是 UI 開發(fā)人員,負(fù)責(zé)盡可能多地創(chuàng)建 Microsoft ASP.NET/Microsoft WinForms。您依賴“中間層”團(tuán)隊(duì)完成其中間層組件 — 這些組件用于執(zhí)行數(shù)據(jù)庫 CRUD (Create-Retrieve-Update-Delete) 以及與該系統(tǒng)中每個(gè)實(shí)體相關(guān)的業(yè)務(wù)規(guī)則。
經(jīng)過幾周的 UI 開發(fā),您完成了窗體并且收到了中間層開發(fā)人員打算向您提交其類庫的消息。表 1 提供一段對話示例,說明我們大多數(shù)人在開發(fā)過程中都會(huì)遇到的一些事情。
| 表 1. UI 開發(fā)人員和中間層開發(fā)人員間的示例對話 | |
| 中間層: | “這些對象隨時(shí)供您使用 — 為此,只需獲取 OurSystemBL.dll 的最新版本。” |
| UI: | “謝謝。您有供我們查看文檔嗎?” |
| 中間層: | “哈哈!是的,當(dāng)然有!我們花了很多時(shí)間編寫它!請查看 Design Document — 噢,請等一等,它還沒有完成……(不久之后即可完成!)” |
| UI: | “您使用 XML 文檔了嗎?” |
| 中間層: | “在構(gòu)造函數(shù)中,但許多方法都不使用。” |
| UI: | “顯示如何創(chuàng)建、執(zhí)行并刪除對象的示例代碼,怎么樣?” |
| 中間層: | “我已經(jīng)附加了一個(gè)示例 WinForms 應(yīng)用程序(從我的工作區(qū)),它應(yīng)該能夠提供一些您所需的內(nèi)容……,雖然它不在 Microsoft Visual SourceSafe 中。” |
在考慮如何進(jìn)行這樣有趣的 項(xiàng)目之后,您打定了主意,決定檢驗(yàn)中間層的單元測試套件。在深入鉆研該代碼之后,您注意到該窗體有兩個(gè)未標(biāo)記的文本框,以及三個(gè)標(biāo)記為 button1、button2 和 button3 的按鈕(幸運(yùn)的話,它們將排列在窗體上)。接下來,在查看與這些按鈕相關(guān)的事件之后,您認(rèn)識(shí)到這些代碼都未經(jīng)注釋,并且數(shù)據(jù)變量都被命名為 x、y、z。如果幸運(yùn),您還會(huì)注意到 button1 和 button2 執(zhí)行該對象的 Save() 方法,而 button3 執(zhí)行 Delete() 方法。執(zhí)行時(shí),您會(huì)接收到很多 System.Exception 錯(cuò)誤,這是因?yàn)檫z漏了很多配置設(shè)置。
這顯然是一個(gè)特例,我希望多數(shù)開發(fā)團(tuán)隊(duì)不要進(jìn)行這一試驗(yàn),下面讓我們看一下該方案中“單元測試”遇到的問題:
| ? | 這種形式的單元測試代碼不是結(jié)構(gòu)化的:代碼充斥到按鈕單擊事件中并且難以編譯。 | ||||
| ? | 這種形式的單元測試代碼記錄得不太好。 | ||||
| ? | 這種形式的單元測試并不基于“已知”為好或壞的數(shù)據(jù) — 它完全依賴于輸入到那些未標(biāo)記的文本框的內(nèi)容。
| ||||
| ? | 實(shí)現(xiàn)的詳細(xì)信息不易于在團(tuán)隊(duì)成員間進(jìn)行傳播。 |
輸入自動(dòng)化單元測試
xUnit 框架在 1998 年作為 eXtreme 編程的核心概念引入。它提出了一個(gè)有效的機(jī)制,有助于開發(fā)人員將結(jié)構(gòu)化、有效且自動(dòng)的單元測試添加常規(guī)開發(fā)活動(dòng)中。從那以后,該框架演化為針對自動(dòng)化單元測試框架的實(shí)際標(biāo)準(zhǔn)。
創(chuàng)建自動(dòng)化單元測試的用例
簡單說,自動(dòng)化單元測試是:
| ? | 結(jié)構(gòu)化的。 |
| ? | 自行記錄的。 |
| ? | 自動(dòng)且可重復(fù)的。 |
| ? | 基于已知數(shù)據(jù)。 |
| ? | 旨在測試積極和消極操作。 |
| ? | 非常適合跨不同計(jì)算機(jī)的測試實(shí)現(xiàn)。 |
| ? | 配置、實(shí)現(xiàn)和執(zhí)行的示例。 |
xUnit 框架元素
表 2 分析 xUnit 框架以及對應(yīng)于 Visual Studio 2005 Team System 的 Unit Testing Framework 等價(jià)物的基本概念。
| 表 2. 相應(yīng)的 xUnit 框架和 VSTS Unit Testing Framework 概念 | ||
| xUnit 框架概念 | VS 2005 等價(jià)物(參見下面的屬性) | 描述 |
| 測試 | TestMethod | 簡單說,這些是您的測試。測試預(yù)期結(jié)果的邏輯,并報(bào)告未取得結(jié)果(如果有)。請將它看作您的“方法”。 |
| 測試裝置 | TestClass | 針對大量測試的一個(gè)邏輯分組。請將它看作您的“類”。 |
| 測試套件 | 測試列表 ** | 針對大量測試裝置的一個(gè)邏輯分組。請將它看作您的“類庫”。 注不需要一個(gè)屬性。 |
| 測試運(yùn)行器 | VS 2005 VSTS Unit Testing Framework | GUI/Console 應(yīng)用程序負(fù)責(zé)發(fā)現(xiàn)、執(zhí)行和報(bào)告測試結(jié)果。Visual Studio 2005 Team System 將作為本文的測試運(yùn)行器。 |
測試裝置示例
請考慮以下針對 BankAccount 類的類關(guān)系圖,以及一個(gè)示例測試裝置 (BankAccountTests.cs)。
圖 1. BankAccount 類
示例測試裝置: 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");}} }主單元測試概念 == 斷言
用于該形式單元測試的主要概念是,自動(dòng)化單元測試是基于“斷言”的,即可定義為“事實(shí)或您相信為事實(shí)的內(nèi)容”。從邏輯角度看,請考慮該語句“when I do {x}, I expect {y} as a result”。
這可以輕松地翻譯為代碼,方法是使用 Microsoft.VisualStudio.QualityTools.UnitTesting.Framework 命名空間中可用的三個(gè)“斷言”類中的任一個(gè):Assert、StringAssert 和 CollectionAssert。主類 Assert 提供用于測試基礎(chǔ)條件語句的斷言。StringAssert 類自定義了在使用字符串變量時(shí)有用的斷言。同樣,CollectionAssert 類包括在使用對象集合時(shí)有用的斷言方法。
表 3 顯示可用于當(dāng)前版本 Unit Testing Framework 的斷言。
| 表 3. VSTS Unit Testing Framework 斷言 | ||
| 斷言類 | StringAssert 類 | CollectionAssert 類 |
| 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)化單元測試用什么運(yùn)行?
正如前面提到的,xUnit 框架將“測試運(yùn)行器”的概念定義為應(yīng)用程序負(fù)責(zé):(a) 執(zhí)行單元測試;(b) 報(bào)告測試結(jié)果。對于本文,包含 Visual Studio 2005 Team System (VSTS) 的 Unit Testing 引擎作為我們的“測試運(yùn)行器”。圖 2 表示 BankAccountTests.cs 類的執(zhí)行結(jié)果。
圖 2. 測試結(jié)果窗格:單元測試執(zhí)行結(jié)果
Microsoft Visual Studio 2005 使用源項(xiàng)目的代碼模型動(dòng)態(tài)填充該視圖。它基于該源代碼中的自定義屬性動(dòng)態(tài)發(fā)現(xiàn)有關(guān)該測試套件的信息。表 4 表示最常見的單元測試屬性(以及執(zhí)行的次序)。
| 表 4. 常見單元測試屬性 | |
| 屬性 | 描述 |
| TestClass() | 該屬性表示一個(gè)測試裝置。 |
| TestMethod() | 該屬性表示一個(gè)測試用例。 |
| AssemblyInitialize() | 在執(zhí)行為執(zhí)行選擇的第一個(gè) TestClass() 中的第一個(gè) TestMethod() 之前,執(zhí)行帶有該屬性的方法。 |
| ClassInitialize() | 帶有該屬性的方法在執(zhí)行第一個(gè)測試之前調(diào)用。 |
| TestInitialize() | 帶有該屬性的方法在執(zhí)行每個(gè) TestMethod() 之前調(diào)用。 |
| TestCleanup() | 帶有該屬性的方法在執(zhí)行每個(gè) TestMethod() 之后調(diào)用。 |
| ClassCleanup() | 帶有該屬性的方法在執(zhí)行 ALL 測試之后調(diào)用。 |
| AssemblyCleanup() | 在執(zhí)行為執(zhí)行選擇的第一個(gè) TestClass() 中的第一個(gè) TestMethod() 之后,執(zhí)行帶有該屬性的方法。 |
| Description() | 提供關(guān)于給定 TestMethod() 的描述。 |
| Ignore() | 由于某種原因忽略 TestMethod() 或 TestClass()。 |
| ExpectedException() | 當(dāng)測試特定異常時(shí),如果使用該屬性指定的異常不是從實(shí)現(xiàn)代碼引發(fā),則測試不會(huì)失敗。 |
我編寫什么類型的測試?
一個(gè)方法及其相關(guān)測試之間很難有一對一關(guān)系。編寫自動(dòng)化單元測試需要開發(fā)人員“進(jìn)行全面思考”,并了解關(guān)于對象的所有內(nèi)容 — 它將如何消耗、使用、處理,以及在任何情況下如何起到積極、消極、非決定性作用。
例如,請考慮一個(gè)用于針對數(shù)據(jù)庫中 Customer 項(xiàng)執(zhí)行 CRUD(創(chuàng)建、檢索、更新、刪除)功能的典型對象方法。對于該對象的 Load() 方法,要針對以下方案編寫測試:
| ? | 構(gòu)造函數(shù)測試 — 確保對象正確加載,帶有正確的信息。 |
| ? | PositiveLoadScalarTest — 測試數(shù)據(jù)庫中一個(gè) Customer 的成功加載。 |
| ? | NegativeLoadScalarTest — 測試一個(gè) Customer 的失敗加載,即該 Customer 不在數(shù)據(jù)庫中。 |
| ? | PositiveLoadTest — 基于已知數(shù)據(jù)測試 Customer 的成功加載。 |
| ? | NegativeLoadTest — 測試數(shù)據(jù)庫中不存在的 Customer 的失敗加載。 |
| ? | NegativeValidationTest — 確保驗(yàn)證邏輯正確工作。 |
這些只是自動(dòng)化單元測試套件許多用法中的一部分。我曾經(jīng)聽說一個(gè)小團(tuán)隊(duì)使用單元測試查看針對其組件的已知安全攻擊。從宏觀的角度來看,單元測試應(yīng)該明確保證組件的正常使用。具有豐富的測試集將使團(tuán)隊(duì)確信您已經(jīng)準(zhǔn)確實(shí)現(xiàn)了既定的目標(biāo):編寫有效的軟件。無論自信源自哪里 — 這就是您需要編寫的測試。
您測試什么?
從本質(zhì)上看,這些自動(dòng)化單元測試非常低級(jí)。它們旨在測試下至構(gòu)造函數(shù)、方法調(diào)用的對象,甚至是對象上的屬性。
關(guān)于“公共對私有”的主題在單元測試派系中引發(fā)了許多爭論。許多人認(rèn)為單元測試只應(yīng)該測試對象的公共接口。其他人認(rèn)為應(yīng)該測試每個(gè)調(diào)用 — 包括內(nèi)部私有方法。VSTS 支持兩個(gè)單元測試級(jí)別。VSTS 通過使用私有訪問器或包裝類支持私有測試,后者提供基于“私有”方法和屬性生成單元測試的功能。
返回頁首為什么生成代碼?
閱讀上面的列表后,您可能會(huì)想起前面項(xiàng)目的單個(gè)對象,并思考:“如果我用“這些”對象進(jìn)行該操作,就需要編寫大量代碼!”請考慮開發(fā)人員仍編寫“單元測試”代碼的事實(shí) — 只在不同的窗體(例如,前面提到的 WinForms 示例)上進(jìn)行。此外,具有可自行記錄、可重用的實(shí)現(xiàn)示例帶來的好處遠(yuǎn)大于生成更多代碼所帶來的麻煩。最后,在單元測試中設(shè)計(jì)更多的環(huán)節(jié)已證明可以減少質(zhì)量保證環(huán)節(jié)中的故障。
正如前面所提到的,代碼生成是“軟件創(chuàng)建軟件”的過程。基于可重復(fù)的過程創(chuàng)建代碼是理想的。例如,一些使用代碼生成的較好示例包括:腳本數(shù)據(jù)、創(chuàng)建表示實(shí)體及其在儲(chǔ)存庫(數(shù)據(jù)庫 CRUD)中存在的對象,或者創(chuàng)建適用于數(shù)據(jù)維護(hù)的 UI 控件。使用代碼生成的好處包括:
| ? | 節(jié)省時(shí)間 — 為什么花幾小時(shí)/天/周創(chuàng)建一些在幾秒/分鐘內(nèi)就可以創(chuàng)建的內(nèi)容? |
| ? | 強(qiáng)制標(biāo)準(zhǔn)/約定— 對于強(qiáng)制您的標(biāo)準(zhǔn)和命名約定而言,沒有什么比消除開發(fā)中的人員因素并依賴基于“您的”規(guī)則的可重復(fù)過程更好的了。 |
| ? | 測試私有方法的功能 — 正如本文前面提到的,Unit Testing Framework 提供使用“私有訪問器”類測試私有方法的功能。該代碼生成引擎創(chuàng)建與這些訪問器類相關(guān)的所有“基礎(chǔ)代碼”。 |
| ? | 獲取現(xiàn)有組件的信息 — 搜索另一個(gè)開發(fā)人員的組件嗎?基于這些組件生成代碼可能提供關(guān)于該實(shí)現(xiàn)以及該對象接口的簡明示例。此外,進(jìn)行設(shè)計(jì)并在編碼之前“清除”其對象的公共接口(例如,通過使用 VS 2005 類設(shè)計(jì)器)的開發(fā)人員將極大地受益于代碼生成引擎。 |
正如您所預(yù)期的,自動(dòng)化單元測試屬于“優(yōu)秀代碼生成候選者”。在現(xiàn)有組件中指出一些內(nèi)容并針對這些自動(dòng)單元測試生成初始代碼難道不是很理想嗎?而且不只是保留單元測試框架,還會(huì)圍繞對象的公共接口生成實(shí)現(xiàn)示例嗎?將來的 Visual Studio 2005 Team System 用戶將擁有該功能以及更多功能!
返回頁首讓我們生成一些代碼吧!
本例中,我們將生成本文前面提到的 BankAccount 類的代碼。本文的這一部分旨在為您介紹代碼生成過程,并重點(diǎn)介紹所提供的功能以及從 VSTS 使用 Unit Testing 引擎的好處。
第 1 步:創(chuàng)建您的實(shí)現(xiàn)代碼
首先,我們創(chuàng)建一個(gè)將用作應(yīng)用程序的業(yè)務(wù)層的類庫項(xiàng)目。
要在 VS 2005 中創(chuàng)建該庫:
| 1. | 啟動(dòng) Visual Studio 2005 Beta 2。 |
| 2. | 單擊 File | New | Project。 |
| 3. | 選擇您選定的語言 Windows,并選擇 Class Library 項(xiàng)目模板。 |
| 4. | 將 Name 和 Solution Name 設(shè)置為 BankAccountDemo.Business,選擇一個(gè)位置,并單擊 OK 來創(chuàng)建該類庫。 |
VS 2005 創(chuàng)建該類后,下一個(gè)任務(wù)就是創(chuàng)建針對您的項(xiàng)目設(shè)計(jì)的 BankAccount 類。為此,需要執(zhí)行以下操作:
| 1. | 在解決方案資源管理器中單擊右鍵,并單擊 Delete,從項(xiàng)目中移除該文件并將其從硬盤中刪除。 |
| 2. | 右鍵單擊 BankAccountDemo.Business 項(xiàng)目,然后單擊 Add,之后單擊 Class。 |
| 3. | 選擇文件名 BankAccount.cs,并單擊 Add 創(chuàng)建類文件。 |
| 4. | 針對 BankAccount.cs 文件對代碼進(jìn)行以下更改。 |
第 2 步:生成您的初始單元測試代碼
由于 Unit Testing 引擎內(nèi)置于 Visual Studio 2005 Team System,因此生成代碼比以前更容易。除了生成單元測試結(jié)構(gòu)之外,它將生成特定于實(shí)例的信息,例如,對象創(chuàng)建、類型化參數(shù)和方法執(zhí)行。
VS 2005 提供在任何類結(jié)構(gòu)級(jí)別生成單元測試代碼的功能,這些級(jí)別包括命名空間、類、方法、屬性、構(gòu)造函數(shù),等等。可通過右鍵單擊這些代碼元素并單擊 Generate test(s)(圖 3)進(jìn)行此操作。
圖 3. Generate test(s) 方法
因此,要開始代碼生成過程,請執(zhí)行以下步驟:
| ? | 右鍵單擊該類名 BankAccount 并單擊 Create Tests。 |
現(xiàn)在,應(yīng)該為您提供 Generate Unit Tests 對話框(如圖 4 所示)。該對話框及其組件提供對該過程中生成的代碼進(jìn)行自定義的功能。讓我們看一下所有這些元素。
圖 4. 生成 Unit Tests 對話框
Current selection: 樹視圖允許導(dǎo)航自定義類及其元素。VS 2005 使用反射填充該樹視圖,并在右鍵單擊以及單擊 Create Tests 的位置自動(dòng)選擇組件。圖 3 中,由于我在類級(jí)別進(jìn)行了此操作,因此該對話框自動(dòng)選擇用于代碼生成的所有類元素。如果選擇在單個(gè)級(jí)別(即,構(gòu)造函數(shù)、屬性或方法)進(jìn)行生成,則只選擇那些元素。
Filter 選項(xiàng)(位于右上角)提供修改樹視圖(圖 5)中所示結(jié)果的功能,包括顯示非公共項(xiàng)、基類型以及“只屬于我的代碼”。如果使用的是大型解決方案,或者感覺顯示私有的內(nèi)部結(jié)構(gòu)會(huì)弄亂選擇窗口,那么這對您很有益處。
圖 5. 篩選選擇結(jié)果
下一個(gè)是 Output project 對話框(位于 Current selection: 樹視圖下)。該列表框允許您針對生成的測試裝置選擇目的項(xiàng)目(圖 6)。如果您的解決方案包含以前創(chuàng)建的測試項(xiàng)目,則將包含該測試項(xiàng)目以供選擇。由于這是我們首次訪問該對話框,因此可以選擇 Create a new … Test Project 選項(xiàng)。
圖 6. 輸出項(xiàng)目選擇
要繼續(xù)我們的過程,請執(zhí)行以下操作:
| ? | 基于您選擇的語言選擇 Create a new {0} Test Project。 |
最后,該對話框提供通過 Settings 按鈕(位于左下角)自定義代碼生成過程的功能。單擊該按鈕將加載 Test Generation Settings 對話框,如圖 7 所示。
圖 7. Test Generation Settings 對話框
該對話框允許您進(jìn)行以下更改:
| ? | 更改命名約定,它們用于生成針對文件、類(測試裝置)和方法(測試)的名稱。 |
| ? | 打開/關(guān)閉使所有測試結(jié)果在默認(rèn)情況下為 Inconclusive 的功能。選擇該選項(xiàng)將在每個(gè)生成的 Test() 方法中包含以下占位符語句。 Assert.Inconclusive("TODO: Implement code to verify target"); |
| ? | 打開/關(guān)閉啟用生成警告的功能 — 即,如果在代碼生成過程中出現(xiàn)任何警告,都要進(jìn)行報(bào)告。 |
| ? | 在全局范圍內(nèi)限制所有類型。該設(shè)置通知代碼生成引擎將一個(gè)全局限定符(在 Microsoft Visual C# 2005 中是 global::)添加到變量聲明中。當(dāng)在多個(gè)命名空間中具有名稱相似的對象時(shí),請使用該設(shè)置。否則,代碼生成引擎將創(chuàng)建邏輯來創(chuàng)建該對象,但是編譯器不能確定創(chuàng)建哪個(gè)類,因此會(huì)產(chǎn)生錯(cuò)誤。 |
| ? | 啟用/禁用針對已具有測試的項(xiàng)生成測試的功能。下面我們將討論關(guān)于后續(xù)代碼生成嘗試的主題。 |
| ? | 啟用/禁用文檔注釋。這允許您在使用每個(gè) Test() 方法時(shí)禁用 XML 文檔的創(chuàng)建 |
要完成我們的配置并生成單元測試代碼(以及更多),請執(zhí)行以下操作:
| 1. | 單擊 OK 按鈕開始代碼生成過程。 |
| 2. | 輸入名稱 BankAccountDemo.Business.Test 作為新項(xiàng)目名,并單擊 Create 按鈕完成該過程。 |
VS 2005 將顯示一個(gè)進(jìn)度欄,提供代碼生成過程中的狀態(tài)。該過程將在幾秒鐘內(nèi)完成,您可以看到一個(gè)名為 BankAccountTest.cs 的類。
返回頁首生成了什么?
在我們對該測試裝置進(jìn)行特別查看之前,讓我們看一下在代碼生成過程中創(chuàng)建了什么。
首先,它創(chuàng)建了 Test Class Library 項(xiàng)目 BankAccountDemo.Business.Test。請注意該項(xiàng)目如何包含對實(shí)現(xiàn)類 BankAccountDemo.Business(您從其中生成代碼)和 Microsoft.VisualStudio.QualityTools.UnitTestFramework 類庫的引用。在查看該類的內(nèi)容時(shí),您將注意到以下文件:
| ? | AuthoringTests.txt — 這是一些信息性的內(nèi)容,定義如何使用單元測試(打開、查看、運(yùn)行、查看結(jié)果、更改測試的運(yùn)行方式),以及 VSTS 中包含的不同測試類型的定義。 |
| ? | ManualTest1.mht — 這是 VSTS 中使用的手動(dòng)測試套件,用于執(zhí)行測試并報(bào)告結(jié)果。手動(dòng)測試是 VSTS 支持的一個(gè)附加測試類型。有關(guān)更多信息,請參閱 MSDN 資源庫的“手動(dòng)測試”主題。 |
| ? | UnitTest1.cs — 這是一個(gè)引用類,它只提供一個(gè)基單元測試(包括 TestClass、TestInitialize、TestCleanup 和 TestMethod 的定義)。 |
| ? | BankAccountTest.cs — 這是特定于程序集生成的單元測試代碼。讓我們仔細(xì)看看該代碼,它是代碼生成過程中最重要的部分。 |
由 Unit Testing 引擎生成的類包括以下組件:
| ? | Using/imports 語句,用于引用的程序集。 |
| ? | TestClass() 定義,用于包含該測試的類 (BankAccountTestFixture)。 |
| ? | 一個(gè)私有訪問器和用于 TestContext 的公共屬性。它由單元測試運(yùn)行器(即 VSTS Unit Test Framework)使用,以便提供關(guān)于當(dāng)前測試運(yùn)行的信息以及用于該運(yùn)行的功能。 |
| ? | TestInitialize() 和 TestCleanup() 方法。這些方法常用于獲取和釋放測試所需的任何對象。 |
| ? | 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."); }請注意該生成引擎除創(chuàng)建一個(gè) stub TestMethod() 對象外,是如何進(jìn)行其他操作的。它創(chuàng)建了適用于接口的示例單元測試,包括:
| ? | BankAccount 對象的分配和結(jié)構(gòu)(測試的對象主題) | ||
| ? | 本地變量的創(chuàng)建和默認(rèn)分配,這些變量表示作為該測試主題的方法/構(gòu)造函數(shù)所需的參數(shù)。
| ||
| ? | 如果測試基于一個(gè)源對象方法調(diào)用,則生成的代碼將包含對該方法(帶有用于這些參數(shù)的局部變量)的調(diào)用。 | ||
| ? | 初始 Assert() 方法調(diào)用,基于該方法的返回值。 | ||
| ? | Assert.Inconclusive() 方法調(diào)用,作為完成測試代碼的提示程序。非確定性測試將在 Test Results 對話框中顯示為失敗。 |
生成后:我現(xiàn)在需要做什么?
考慮要完成相同的操作可以不必做哪些事情,則通常可以認(rèn)識(shí)到代碼生成的好處。在我們的示例中,我們不必:
| ? | 創(chuàng)建單元測試項(xiàng)目。 |
| ? | 設(shè)置項(xiàng)目引用。 |
| ? | 添加適當(dāng)?shù)臏y試類(一個(gè)或多個(gè))。 |
| ? | 生成主干 Unit Test Framework 類和屬性。 |
| ? | 創(chuàng)建單個(gè)測試方法。 |
| ? | 創(chuàng)建特定于接口的邏輯。 |
由于代碼生成過程創(chuàng)建了特定于對象接口的示例單元測試,因此我們接近于初始測試的完成階段了。通常情況下,只需“填充空白”并完成斷言(一個(gè)或多個(gè)),方法是將“已知的數(shù)據(jù)值”分配給屬性變量并創(chuàng)建適當(dāng)?shù)?Assert() 方法。顯然,這不是針對所有測試的示例,特別是對具有多個(gè)斷言的復(fù)雜測試而言。
只需幾秒鐘的時(shí)間(使用相對較少的擊鍵),您就能夠?qū)⑸傻膯卧獪y試代碼轉(zhuǎn)換為這些實(shí)際的測試。
例如,請考慮我們以如下方式開始。
[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."); }我們能夠完成相對容易且具有有限擊鍵的測試(更改部分用黑體表示)。
[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"); } 返回頁首重新生成單元測試代碼
好消息是,代碼生成過程不會(huì)讓您重寫以前生成(和修改)的單元測試。使用 Visual Studio 2005 Team System 的 Beta 2 版本,代碼生成選項(xiàng)提供一個(gè)啟用/禁用創(chuàng)建已存在測試的復(fù)選框。如果選擇它,而且該過程找到了一個(gè)具有相同名稱的現(xiàn)有測試,則該過程將忽略該測試方法,并創(chuàng)建后續(xù)測試,從而將一個(gè)數(shù)字附加到該方法名的末尾。這通常在對象中使用重載的方法或構(gòu)造函數(shù)時(shí)發(fā)生,或者當(dāng)單擊 Generate 按鈕而不取消選定現(xiàn)有測試時(shí)發(fā)生。
返回頁首自動(dòng)化單元測試建議
雖然本節(jié)可以獨(dú)立成文,但這里只是一些您在創(chuàng)建單元測試時(shí)可以采納的基本建議。
| ? | 設(shè)計(jì)彼此獨(dú)立的單元測試,其中它們可以獨(dú)立運(yùn)行(由于可以通過測試 UI 隨意選擇或取消選定它們)。 | ||||
| ? | 不要只進(jìn)行正面測試。請確保代碼能夠響應(yīng)任何方案,包括發(fā)生意外時(shí)(資源不可用,數(shù)據(jù)庫只讀等)。 | ||||
| ? | 把自己當(dāng)作一個(gè) QA 人員,想象成一個(gè)測試人員,而不僅僅是一個(gè)開發(fā)人員。您花在設(shè)計(jì)單元測試上的時(shí)間將有助于減少日后解決故障所用的時(shí)間。請注意對象的幾個(gè)小細(xì)節(jié):數(shù)據(jù)如何在對象之間傳輸?誰使用它們?銷毀對象容易嗎?如果我“進(jìn)行此操作”,將會(huì)發(fā)生什么? | ||||
| ? | 跳出您自己的思維模式。盡可能多地對測試進(jìn)行頭腦風(fēng)暴。當(dāng)您完成時(shí),回頭查看您可能漏掉的內(nèi)容。來自團(tuán)隊(duì)成員的請求反饋 — 例如,他們創(chuàng)建了什么其他類型的測試?其他人可能提供一個(gè)對熟悉自己代碼的開發(fā)人員而言非常困難的觀點(diǎn)。 | ||||
| ? | 代碼覆蓋。使用 VSTS 代碼覆蓋規(guī)范提供有關(guān)每個(gè)測試運(yùn)行中實(shí)際執(zhí)行多少代碼的信息(代碼的行數(shù),占所有代碼的百分比)。如果編碼完成,并且通過了所有測試,但代碼覆蓋顯示只執(zhí)行了該邏輯的一小部分,那么您的測試真的成功了嗎?高代碼覆蓋不一定意味著您具有一個(gè)完整的“測試”集,而未覆蓋的代碼通常非常適用于一個(gè)新的測試用例。 | ||||
| ? | 當(dāng)生成單元測試時(shí),要幫助其他人了解您的代碼:
| ||||
| ? | 此外,當(dāng)其他所有測試都失敗時(shí),請進(jìn)行調(diào)試。自動(dòng)化單元測試應(yīng)該有助于減少您用在調(diào)試器上的時(shí)間。但是,如果測試結(jié)果和代碼覆蓋無法提供測試失敗的原因,那么您大可不必?fù)?dān)心調(diào)試單元測試。從 Beta 2 版的 Visual Studio 2005 Team System 開始,開發(fā)人員可以使用 Test Manager 中的 Debug checked tests 選項(xiàng)調(diào)試他們的單元測試程序集。 |
小結(jié)
自動(dòng)化單元測試為開發(fā)環(huán)節(jié)提供了一個(gè)結(jié)構(gòu)化、自行紀(jì)錄、高度便攜且可重復(fù)的過程。如果在搜索現(xiàn)有程序集,或者如果開發(fā)環(huán)境需要在開始開發(fā)之前進(jìn)行完整的設(shè)計(jì),則請考慮使用內(nèi)置到 Microsoft Visual Studio 2005 Team System 中的代碼生成引擎。Visual Studio 2005 Team System 的單元測試代碼生成功能可以為您節(jié)省寶貴的時(shí)間,而且有助于強(qiáng)制團(tuán)隊(duì)的開發(fā)標(biāo)準(zhǔn)和約定。通過生成用于自動(dòng)化單元測試的基本內(nèi)容,包括生成帶有對象創(chuàng)建的測試方法、參數(shù)變量和基斷言類,您應(yīng)該能夠順利地在您的開發(fā)方法論中采用自動(dòng)化單元測試。
轉(zhuǎn)載于:https://www.cnblogs.com/jacklaw/archive/2007/12/04/982242.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的使用 Visual Studio 2005 Team System 进行单元测试并生成用于 Unit Test Framework 的源代码...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汪学明导师—商业模式创新与转型专家
- 下一篇: 英语26个字母使用频度