程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Visual Studio 2010:測試驅動的開發

Visual Studio 2010:測試驅動的開發

編輯:關於.NET

概述

測試驅動開發 (Test Driven Development, TDD),通常也稱作測試驅動設計,是一種開發方法。在該方法中,開發人員首先編寫單元測試,然後編寫實際系統代碼來確保可以順利通過單元測試。可以將單元測試看作是系統行為的小型規范;首先編寫單元測試可以讓開發人員僅編寫足夠通過測試的代碼,有助於確保系統的緊湊、輕量,並能明確專注於滿足已確定的需求。

TDD 的步調是“紅色、綠色和重構。”紅色表示失敗測試的可視顯示——最初編寫的測試並不會通過,因為您還沒有為它編寫任何代碼。綠色表示在系統中編寫足夠的代碼以確保單元測試能順利通過——測試運行器的用戶界面現在將使用綠色圖標表示測試順利通過。重構表示對代碼執行重構來提高它的緊湊性、簡潔性和靈活性。在 TDD 開發人員的工作中,此周期將不斷重復。

注意:本實驗的目的並不是指導您如何使用 TDD;而是重點展示 Visual Studio 2010 對 TDD 的支持。如果您對 TDD 方法及其優勢感興趣,建議首先閱讀以下圖書,以之作為起點:

Test Driven Development in Microsoft .NET  作者:James Newkirk 和 Alexei Voronstov,ISBN 0735619484

Pragmatic Unit Testing in C# with NUnit, 2nd Edition 作者:Andy Hunt、Dave Thomas 和 Matt Hargett,ISBN 0977616673

TDD 的關鍵是開發人員的步調。要實現高效的開發節奏,開發人員需要擁有正確的思想,同時還要借助正確的工具來盡量提高工作速度和減少沖突。

Visual Studio 2010 引入了一些增強功能,有助於減少開發阻礙並支持開發人員專注於以下任務:編寫高質量的代碼。在接下來的練習中,我們將重點展示一些新特性,它們可以幫助開發人員改善其開發步調。VS10 可以幫助開發人員減少常用任務的敲鍵數量,加速解決方案導航,同時使用測試框架來代替 MSTest。

為了演示其新特性,我們將采用“測試優先”的方式實現一個棧,展示如何利用測試來驅動 SimpleStack 類的設計和實現。

注意:在計算機科學領域,棧是一種抽象的數據類型和數據結構,采用後進先出 (LIFO) 的原則。

如果您不熟悉棧這個數據結構概念,或者想回顧一些相關知識,請閱讀更加全面的 Wikipedia 文章,更加深入地了解此概念。

目標

在本次動手實驗中,您將學習如何:

使用新的智能標記操作來減少擊鍵次數,讓 IDE 自動生成小型的代碼片段。

使用 Quick Search 迅速導航代碼庫。

系統要求

您必須擁有以下內容才能完成本實驗:

Microsoft Visual Studio 2010 Beta 2

.Net Framework 4.0

安裝

使用 Configuration Wizard 驗證本實驗的所有先決條件。要確保正確配置所有內容,請按照以下步驟進行。

注意:要執行安裝步驟,您需要使用管理員權限在命令行窗口中運行腳本。

1.如果之前沒有執行,運行 Training Kit 的 Configuration Wizard。為此,運行 %TrainingKitInstallationFolder%\Labs\TestDrivenDevelopment\Setup 文件夾中的 CheckDependencies.cmd 腳本。安裝先決條件中沒有安裝的軟件(如有必要請重新掃描),並完成向導。

注意:為了方便,本實驗管理的許多代碼都可用於 Visual Studio 代碼片段。CheckDependencies.cmd 文件啟動 Visual Studio 安裝程序文件安裝該代碼片段。

練習

本次動手實驗由以下練習組成:

1.為您的設計添加測試動力,即編寫測試並讓它們從紅色(失敗)變為綠色(通過)。

2.重構代碼,運行測試並確保它們全部通過。

完成本實驗的估計時間:60 分鐘。

注意:本實驗同時使用 C# 和 VB.NET 演示代碼示例;但是,屏幕快照僅反映 C# 的實驗操作。VB.NET 的操作與屏幕快照相似。

下一步

練習 1:紅色、綠色…

練習 1:紅色、綠色……

在本練習中,您將使用 Visual Studio 2010 中支持 TDD 工作流的新特性。您將了解智能標記操作、測試運行器增強和一些導航特性。

任務 1 –創建新項目

在此任務中,您將創建一個 C# 或 VB 類庫和測試項目,並通過它們體驗 Visual Studio 中新增的 TDD 特性。

1.從 Start | All Programs | Microsoft Visual Studio 2010 | Microsoft Visual Studio 2010 打開 Microsoft Visual Studio。

2.在 Visual Studio Start Page 中,單擊 New Project 按鈕。

圖 1

創建項目

3.在 New Project 對話框中,選擇 Visual C# 或 VB 項目類型。確保選中了 .NET Framework 4.0,然後選擇 Class Library 模板。

4.將項目的名稱更改為 SimpleDataStructures,確保選中了 Create directory for solution 復選框,然後單擊 OK。

5.刪除 New Project Wizard 創建的默認 Class1.cs 文件(或 Class1.vb)。

圖 2

刪除 New Project Wizard 創建的默認文件。

6.在 Solution Explorer 中,右鍵單擊 SimpleDataStructures 解決方案並單擊 Add | New Project…,然後選擇 Visual C# | Test 或 Visual Basic | Test 項目類型。確保選中了 .NET Framework 4.0,然後選擇 Test Project。

7.將項目名稱更改為 SimpleDataStructures.Tests 並單擊 OK。

8.刪除 New Project Wizard 創建的 UnitTest1.cs 文件(或 UnitTest1.vb)。

圖 3

刪除 New Project Wizard 生成的默認測試文件。

任務 2 –為測試定義上下文。

在此任務中,您將編寫一些測試來幫助設計 SimpleStack 類。

我們將創建一個新文件來保存 SimpleStack 類的一些測試,然後開始編寫第一個測試。在此過程中,我們將使用新的智能標記操作來關聯一些必要的導入語句,執行一些微代碼生成等。

1.在 Solution Explorer 中,右鍵單擊 SimpleDataStructures.Tests 項目並選擇 Add | Class。確保選中了 Visual C# Items | Code (或 VB.NET 中的 Common Items | Code),然後選擇 Class 模板。

2.將名稱更改為 SimpleStackTests 並單擊 Add 按鈕。

3.Visual Studio 將打開新的 SimpleStackTests.cs 文件(或 SimpleStackTests.vb)。您的解決方案應類似於圖 4。

圖 4

新 SimpleStackTests.cs 文件

4.Visual Studio 會自動將新生成的類默認設置為內部類,但必須公開這些類以便測試運行器能找到並運行測試。添加 public 關鍵字,如以下代碼所示。

C#

namespace SimpleDataStructures.Tests
{
    public class SimpleStackTests
    {
    }
}

注意:Visual Basic 默認將創建具有公共作用域的類,並且這些類文件不包含命名空間,除非您需要手動修改默認值。

Visual Basic

Public Class SimpleStackTests

End Class

5.接下來,我們需要使用 TestClassAttribute 修飾這個類,以便 Visual Studio Test Runner 能將該類識別為測試窗實體。將 TestClass 屬性添加到 SimpleStackTests 類。

C#

namespace SimpleDataStructures.Tests
{
    [TestClass]
public class SimpleStackTests
    {
    }
}

Visual Basic

<TestClass()> Public Class SimpleStackTests

End Class

6.注意,這裡存在一個問題– Visual Studio 並不能識別 TestClass 屬性,因為該文件缺少一個 using 語句。

7.您可以使用 Visual Studio 2010 中新增的智能標記操作自動糾正 using(VB.Net 中則為 Imports)語句。按下 CTRL + .觸發智能標記上下文菜單,並選擇第一個選項。

圖 5

使用智能標記添加缺失的 using 語句

8.我們定義了一個測試實體,但在開始編寫測試之前,我們需要為測試設置一些上下文。 

注意:TDD 中的“上下文”用於描述 SimpleStack 的當前條件和狀態。“上下文”允許我們清楚地描述測試的目的。將測試描述為普通描述性文本而不是軟件代碼是非常有益的。

此外,我們將為測試實體和測試方法使用較長且更具描述性的名稱。其目標是在測試的命名中傳達需求的本質,並讓測試主體(代碼)能傳達其機理。

雖然這看上去有些奇怪並且有悖於關於編寫代碼的一些既定的常理,但它在許多 TDD & BDD 實踐中卻非常有用。

9.我們首先假定已創建了棧,這表示它處於默認狀態。要設置此上下文,將 SimpleStackTests 類重命名為更具描述性的文本,比如:

C#

public class WhenAStackIsCreated
{
}

Visual Basic

<TestClass()> Public Class WhenAStackIsCreated

End Class

任務 3 –編寫第一個測試:設計和定義 SimpleStack

在此任務中,您將開始設計和構建 SimpleStack 類,這需要使用任務 2 中定義的上下文創建一個測試。在此過程中,我們將使用新的智能標記操作來關聯必要的 using 語句,執行一些微代碼生成等。

1.首先,創建一個新的測試方法,指明新創建的棧應該為空。使用 TestMethodAttribute 修飾該方法。注意測試類與測試方法名稱之間的關系:WhenAStackIsCreated.ThenItShouldBeEmpty()。這種命名約定將幫助我們更好地理解各項測試的目的。

(代碼片段 – TDD 實驗 - 練習 1 ThenItShouldBeEmpty C#)

C#

[TestMethod]
public void ThenItShouldBeEmpty()
{
}

(代碼片段 – TDD 實驗 - 練習 1 ThenItShouldBeEmpty VB)

Visual Basic

<TestMethod()> Public Sub ThenItShouldBeEmpty()

End Sub

2.接下來,我們需要聲明並使用一個新的 SimpleStack,然後驗證其 IsEmpty 屬性返回值是否為 true。首先,聲明並初始化一個新的 SimpleStack。

C#

[TestMethod]
public void ThenItShouldBeEmpty()
{
    SimpleStack theStack = new SimpleStack();
}

Visual Basic

<TestMethod()> Public Sub ThenItShouldBeEmpty()
    Dim theStack As New SimpleStack
End Sub

3.注意,Visual Studio 仍然會為您提供一個智能標記,但其原因與之前不同。在本例中,Visual Studio 並不知道 SimpleStack 類是什麼,因此它將為您生成一個測試存根。

圖 6

未定義類的智能標記選項

4.從列表中選擇 Generate class for "SimpleStack"(VB.Net 則為 Generate ‘Class SimpleStack’)。此時將打開一個新窗口,並為新類生成一個測試存根。從 Solution Explorer 中打開 SimpleStack.cs 或 SimpleStack.vb 文件。

圖 7

SimpleStack 類的測試存根

注意:上面的智能標記提供了第二個選項,即“Generate other…”,可允許您自定義要生成的代碼。如果選擇該選項,則會看到以下內容:

需要特別注意項目位置選項。默認情況下,智能標記會在當前項目中生成測試存根代碼,但這並不是您所期望的行為。項目位置字段允許您在完全不同的位置創建生成的代碼。

值得重點注意的是,TDD 純粹主義者將使用智能標記方法,直接在當前工作的位置生成代碼。這種精妙的設計方法支持開發人員盡可能晚地做出基本的設計選擇。在我們的小型解決方案中,這顯然就是保存生成的代碼的位置;但是,在較大的項目中,我們可以有 20 或 30 個不同的組件。我們的代碼可能需要由各種不同的組件訪問。我們如何能在開發周期的早期准確知道哪些組件需要訪問我們開發的代碼呢?

在開發周期的晚期確定移動代碼的位置,這意味著我們可以更加明確地掌控系統中的潛在依賴關系,並且能更加明智地確定保存代碼的位置。所有這些都回到了最基本的原則上:通過最簡單的工作讓測試順利通過。

(要了解如何在最後時刻做出關鍵決策,我們強烈建議您閱讀 Tom 和 Mary Poppendeick 編寫的 Lean Software Development 一書。)

在本例中,我們在 SimpleDataStructures.Tests 項目中觸發了智能標記,但我們希望 SimpleStack 實現位於 SimpleDataStructures 項目和命名空間中。為此,我們可以在此對話框中選擇相應的項目位置。

5.返回到測試,我們將驗證棧是否為空,方法是斷言其 IsEmpty 屬性為 true。

C#

[TestMethod]
public void ThenItShouldBeEmpty()
{
SimpleStack theStack = new SimpleStack();

    Assert.IsTrue(theStack.IsEmpty);
}

Visual Basic

<TestMethod()> Public Sub ThenItShouldBeEmpty()
Dim theStack As New SimpleStack

    Assert.IsTrue(theStack.IsEmpty)
End Sub

6.您會再次看到一個智能標記,這一次用於在 SimpleDataStructures.Tests.SimpleStack 中為 IsEmpty 生成屬性存根。選擇此選項將在 SimpleStack 類中生成一個公共的自動屬性。

圖 9

顯示創建方法存根選項的智能標記

7.切換到 SimpleStack.cs 文件(或者 SimpleStack.vb),您將看到添加了存根的屬性。

圖 10

添加了存根的 IsEmpty 屬性

8.現在運行測試,方法是右鍵單擊測試方法並選擇 Run Tests(或鍵入 Ctrl+R, T)。您將看到 IsEmpty 返回 true 的斷言失敗了,因此測試也失敗了。

9.在 TDD 模式中,我們將通過最簡單的工作讓測試通過,只需要 getter 返回 true!

注意:這看上去有些不可理解;但是,它具有多個方面的重要性。首先,您將檢查剛才編寫的測試。如果測試未通過,則說明測試中包含錯誤,比如需要檢查false 值時卻檢查了 true 值。其次,這實現了用最簡單的工作通過測試的概念。

作為此概念的一部分,我們還將自動屬性(可讀寫)修改為只讀屬性。我們這樣做的目的在於通過最少的功能和代碼來通過測試。測試並未指定需要寫入棧,因此我們不會允許代碼具備該功能。我們將確保代碼的簡潔性,這將改善易讀性並減少漏洞。(代碼越少意味著漏洞越少!)

C#

class SimpleStack
{
public bool IsEmpty
    {
        get { return true; }
    }
}

(代碼片段 – TDD 實驗 - 練習 1 IsEmpty 返回 True VB)

Visual Basic

Public Class SimpleStack
    Public ReadOnly Property IsEmpty() As Boolean
        Get
            Return True
        End Get
    End Property
End Class

10.接下來需要返回測試;但是,您不需要將手移開鍵盤,而去使用鼠標。相反,借助 Quick Search 屬性,您只需單擊幾個鍵就可以迅速導航到代碼庫。按住 CTRL + ,(即 Control 和一個逗號)觸發 Quick Search 對話框,然後鍵入文件、類或方法的名稱。Quick Search 將為您篩選出代碼庫中可用位置的列表。完成篩選並找到代碼中的適當位置後,使用向上和向下箭頭鍵突出顯示選項並按回車鍵。

圖 11

使用 Quick Search 直接導航到特定方法

注意:Visual Studio 將導航到代碼庫中的該位置,將光標置於類名或方法名的開始處即可!

11.現在,您已經回到了測試方法中,重新運行測試。這次應該能順利通過!

圖 12

測試通過!

任務 4 –添加更多測試驅動的功能

此時, 我們已經完成了 SimpleStack 實現的空框架。它只有一個有效成員:一個只讀屬性。我們可以通過測試協助設計來繼續添加功能。現在,我們來看看如何在 SimpleStack 中添加或刪除項目。

1.添加一個新測試,為 SimpleStack 指定一個新的 Push 方法,它接受整型值:

(代碼片段 – TDD 實驗 - 練習 1 ThenShouldBeAbleToPushAnItemOntoTheStack C#)

C#

[TestMethod]
public void ThenShouldBeAbleToPushAnItemOntoTheStack()
{
    var theStack = new SimpleStack();
    theStack.Push(1);
}

(代碼片段 – TDD 實驗 - 練習 1 ThenShouldBeAbleToPushAnItemOntoTheStack VB)

Visual Basic

<TestMethod()> Public Sub ThenShouldBeAbleToPushAnItemOntoTheStack()
    Dim theStack As New SimpleStack
    theStack.Push(1)
End Sub

2.在 Push 方法調用下,您應該可以看到一個智能標記。單擊 CTRL + .觸發智能標記,它允許為 Push 方法生成一個方法存根。按下回車鍵讓 Visual Studio 生成存根。

圖 13

使用智能標記生成方法存根

3.現在,運行測試並確保它失敗。

注意:此時運行測試看上去有些奇怪,因為我們知道 Visual Studio 添加的存根會造成測試運行失敗。但是,TDD 的一個重要部分就是紅色–綠色–重構的步調,而此步調中的一個關鍵步驟就是確保像預期那樣失敗。

這為何如此重要呢?因為測試難免會意外通過,這與預期不符。在這些情況下,我們需要確保測試指定了正確的行為並修復了錯誤的行為。

4.我們的新目標是讓此測試通過。在 TDD 模式下,我們將用最簡單的工作讓測試變為綠色:我們將刪除 Push 方法中的 NotImplementedException!此時,我們不會向方法添加任何實現,測試僅檢查是否成功推入了一些對象到棧中。

C#

internal void Push(int p)
{
}

Visual Basic

Sub Push(ByVal p As Integer)

End Sub

5.使用 Quick Search (CTRL + ,) 返回調試,方法是在搜索框中輸入“TSBA”。

6.注意,Quick Search 將匹配大寫字母 TSBA 與測試名稱中的大寫字母,並找到 ThenShouldBeAbleToPushAnItemOntoTheStack。

 

圖 14

使用 Quick Search 進行篩選和導航,僅需使用類、方法或文件名中的大寫字母

7.重新運行測試,它應該能順序通過。綠色!遺憾的是,推送方法此時的作用並不大,因此我們將在稍後繼續使用它。

下一步

練習 2:重構!

練習 2:重構!

當我們剛才創建的系統代碼通過測試時,可以看出它顯然是沒有任何意義的。現在,我們將重構這個最簡單的示例,讓它在通過測試的同時完成一些有意義的任務。現在,我們將進入重構階段。

任務 1 –從通過測試轉移到構建功能

1.從 Start | All Programs | Microsoft Visual Studio 2010 | Microsoft Visual Studio 2010 打開 Microsoft Visual Studio 2010。

2.打開 SimpleDataStructures.sln 解決方案文件。默認情況下,該文件位於以下文件夾:%TrainingKitInstallFolder%\Labs \TestDrivenDevelopment\Source\Ex02-Refactor\begin\ ,並選擇您喜歡的語言。您也可以繼續使用上一個練習完成時獲得的解決方案。

3.我們需要能夠驗證將項目推送到棧中是否能實際修改棧,也就是在 Push 操作完成後;該棧存放我們所需的對象。一種驗證方法是確保棧在推入項目後不再為空。

4.更新相應測試:

C#

[TestMethod]
public void ThenShouldBeAbleToPushAnItemOntoTheStack()
{
var theStack = new SimpleStack();
theStack.Push(1);

Assert.IsFalse(theStack.IsEmpty);
}

Visual Basic

<TestMethod()> Public Sub ThenShouldBeAbleToPushAnItemOntoTheStack()
Dim theStack As New SimpleStack
theStack.Push(1)
Assert.IsFalse(theStack.IsEmpty)
End Sub

5.現在運行測試,它應該會失敗。為什麼會失敗呢?

6.記住,我們在 IsEmpty 實現中盡可能保證了工作的簡單性,同時確保它始終返回 true 值。現在,我們需要確定 IsEmpty 的實際行為,以及它對 Push 方法的意義。

注意:測序驅動開發通常也稱作測試驅動設計,其原因在於,我們將定義系統的行為,並通過設計以迭代的方式交付該行為。

7.返回 SimpleStack 類之後,通過仔細觀察,我們發現棧需要通過某種機制來存儲一些狀態,特別是棧所存放的項目的狀態。

8.將項目存儲在列表中允許我們確定棧是否為 IsEmpty(通過檢查列表的大小)。我們還可以在其中存儲推入的項目。

(代碼片段 – TDD 實驗 - 練習 1 重構 SimpleStack C#)

C#

class SimpleStack
{
    ArrayList _items;

    public bool IsEmpty
    {
        get { return _items.Count == 0; }
    }

    internal void Push(int p)
    {
        _items.Add(0);
    }
}

(代碼片段 – TDD 實驗 - 練習 2 重構 SimpleStack VB)

Visual Basic

Class SimpleStack
    Private _items As ArrayList

    Public ReadOnly Property IsEmpty() As Boolean
        Get
            Return (Me._items.Count = 0)
        End Get
    End Property

    Friend Sub Push(ByVal p As Integer)
        Me._items.Add(0)
    End Sub
End Class

9.注意 ArrayList 類型未被識別。按下 CTRL+.並選擇導入 System.Collections 命名空間。

10.現在運行測試。您會驚訝地發現測試仍然失敗了。測試失敗的原因是我們未初始化 ArrayList。可以看到 Visual Studio 通過綠色的波浪式下劃線提示了這個問題:

圖 15

提醒未初始化字段的綠色波浪式線條和工具提示

11.添加一個默認的構造函數並在構造函數中初始化列表,如以下代碼所示。

(代碼片段 – TDD 實驗 - 練習 2 SimpleStack 構造函數 C#)

C#

class SimpleStack
{
ArrayList _items;

    public SimpleStack()
    {
        _items = new ArrayList();
    }
    …
}

(代碼片段 – TDD 實驗 - 練習 2 SimpleStack 構造函數 VB)

Visual Basic

Class SimpleStack
Private _items As ArrayList

    Public Sub New()
        Me._items = New ArrayList
    End Sub
                …
End Class

12.再次運行測試,這次將順利通過!

13.我們如何知道是否存儲了正確的項目呢?我們所做的全部工作就是在棧中推入了一些項目。在本例中,我們在實驗的早期步驟中,為了確保簡單性向棧中添加了一個零 (0) 值。

圖 16

盡可能簡單地通過測試

14.這樣做的作用並不大。我們需要實現更多功能。

15.添加一個新測試,首先向棧推入一個項目,然後彈出一個項目,並確保我們向棧中推入了該項目。

(代碼片段 – TDD 實驗 - 練習 2 ThenShouldBeAbleToPushAndPopAnItemFromTheStack C#)

C#

[TestMethod]
public void ThenShouldBeAbleToPushAndPopAnItemFromTheStack()
{
    var theStack = new SimpleStack();
    theStack.Push(1);

    int poppedItem = theStack.Pop();

    Assert.AreEqual(1, poppedItem);
}

(代碼片段 – TDD 實驗 - 練習 2 ThenShouldBeAbleToPushAndPopAnItemFromTheStack VB)

Visual Basic

<TestMethod()> Public Sub ThenShouldBeAbleToPushAndPopAnItemFromTheStack ()
    Dim theStack As New SimpleStack
    theStack.Push(1)
    Dim poppedItem As Integer = theStack.Pop()
    Assert.AreEqual(1, poppedItem)
End Sub

16.我們會再次看到新定義的 Pop 方法下方出現了智能標記。

圖 17

使用智能標記生成方法存根,並使用正確的返回類型

17.觸發智能標記並讓它為 Pop 方法生成一個方法存根,然後使用 Quick Search (CTRL + ,) 導航到新的帶有存根的方法。

18.注意,Visual Studio 能夠確定 Pop 需要返回一個值,並且它會推斷出正確的返回類型,在本例中為 int。

C#

internal int Pop()
{
throw new NotImplementedException();
}

Visual Basic

Function Pop() As Integer
                Throw New NotImplementedException
End Function

19.運行測試,它將會失敗並出現 NotImplementedException 錯誤,但現在我們定義了 Pop 在此上下文中的外觀和行為,我們可以添加實現細節讓測試通過。

(代碼片段 – TDD 實驗 - 練習 2 Pop 實現 C#)

C#

internal int Pop()
{
    int value = (int) _items[0];
    _items.RemoveAt(0);

    return value;
}

(代碼片段 – TDD 實驗 - 練習 2 Pop 實現 VB)

Visual Basic

Function Pop() As Integer
    Dim value As Integer = CInt(Me._items.Item(0))
    Me._items.RemoveAt(0)
    Return value
End Function

20.再次運行測試,結果仍然會失敗。這是為什麼呢?Pop 方法看上去沒有問題,但本機 Push 實現出現了問題,所以測試失敗了。是時候解決它了!

C#

internal void Push(int p)
{
    _items.Add(p);
}

Visual Basic

Friend Sub Push(ByVal p As Integer)
    Me._items.Add(p)
End Sub

21.運行測試,三個測試全部通過!

注意:本實驗的主旨並不是深入討論測試驅動開發的原理與實踐,也不是如何正確地實現棧。

但是,如果我們繼續設計和構建 SimpleStack,則需要繼續思考如何在空棧上調用 Pop。此外,嘗試操作滿棧會出現什麼問題?或者填充了一部分的棧呢?

要解決這些設計問題,我們需要在 SimpleStackTests.cs 文件中引入一些新的測試實體,以及更多測試。

此外,您可能已注意到實現中還有一個 bug!我們將項目推送到 Stack 末端,但它卻從前面彈出了!我們在繼續演示推入和彈出多個項目時會解決這個問題。

任務 2 –重組代碼

有時,我們需要確定將 SimpleStack 實現從 SimpleDataStructures.Tests 項目移到 SimpleDataStructures 項目和命名空間中所需的時間。我們已在使用“Generate Other…”智能標記操作創建類的時候完成此任務(參見:練習 1,任務 #3,步驟 #2)。但是,我們選擇了采用最簡單的方式,並讓 Visual Studio 使用默認設置,即在智能標記觸發時在當前項目(SimpleDataStructures.Tests)中生成類。

1.使用 Visual Studio Solution Explorer,從 SimpleDataStructures.Tests 項目中選擇 SimpleStack.cs 文件(或 SimpleStack.vb)。右鍵單擊並選擇 Cut,然後在 SimpleDataStructures 項目中右鍵單擊並選擇 Paste。此時,Solution Explorer 應該類似於下圖:

圖 18

移動 SimpleStack.cs 文件後的解決方案結構

2.打開 SimpleStack.cs 文件並將命名空間更改為 SimpleDataStructures。按下 Ctrl-S 保存文件。如果使用 VB.Net 則不需要此步驟。

C#

namespace SimpleDataStructures

3.導航到測試,您會注意到所有紅色的波浪線。再次返回 SimpleStack.cs 文件(或 SimpleStack.vb),並查看 SimpleStack 類的定義。當 Visual Studio 生成類之後,它會采用最簡單的方式默認將類創建為內部類,因為當前只需要這樣的可見性。現在,我們已經將類重構到不同的項目和命名空間中,接下來需要調整其可見性。

C#

namespace SimpleDataStructures
{
    public class SimpleStack
    {
        …
    }
}

Visual Basic

Public Class SimpleStack
                                …
End Class

4.除了這些代碼,我們還需要將 Push 和 Pop 方法的可見性更改為公共。

C#

public void Push(int p)
{
_items.Add(p);
}

public int Pop()
{
int value = (int) _items[0];
_items.RemoveAt(0);

return value;
}

Visual Basic

Public Sub Push(ByVal p As Integer)
Me._items.Add(p)
End Sub

Public Function Pop() As Integer
Dim value As Integer = CInt(Me._items.Item(0))
Me._items.RemoveAt(0)
Return value
End Function

5.最後,我們還需要從 SimpleDataStructures.Tests 項目中引用 SimpleDataStructures 項目。在 Solution Explorer 中右鍵單擊 References,然後選擇 Add Reference。單擊 Add Reference 對話框中的 Projects 選項卡,選擇 SimpleDataStructures 項目,然後單擊 OK。

圖 19

添加對 SimpleDataStructures 項目的引用

6.再次運行測試,全部測試順利通過!

總結

在本實驗中,您了解了一些針對采用“測試優先”開發模式的開發人員的全新 IDE 增強。其中,導航改進可幫助您更加輕松快捷地在代碼庫中導航。IDE 可以幫助您為測試類中的方法添加存根,甚至將該代碼推送到完全不同的文件中。您甚至了解了通過測試運行器查看代碼和設計和狀態是多麼簡單。

最後,或許也是重要的一點,如果您剛開始接觸測試驅動設計/開發,希望您了解了如何借助 Visual Studio 采用這種激動人心的方法來創建簡潔、緊湊和高質量的軟件。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved