2010-12-09 33 views
18

我正在嘗試學習TDD,但很難找到我需要編寫的一個小應用程序測試什麼/如何測試。用一個簡單的例子學習TDD

的(簡化的有點)規範的應用程式如下:

它需要從用戶採取csv文件的位置,Word文檔郵件合併模板的位置和輸出位置。

該應用程序將讀取CSV文件,併爲每一行,將數據與單詞模板合併並輸出到指定的文件夾。

爲了清楚起見,我不問我會如何去編寫這樣的應用程序,因爲我相信如果我只是繼續前進並開始,我就知道如何去做。但是如果我想用TDD來完成這項工作,那麼有關編寫測試的一些指導將值得讚賞,因爲我猜測我不想測試讀取真正的csv文件,或測試合併的第三方組件或轉換爲pdf。

我認爲只是一些一般的TDD指導將是一個很大的幫助!

回答

26

我開始時會考慮你編的每一步的場景RAM,失敗案例及其預期的行爲開始:

  • 用戶提供了一個空的CSV文件位置(拋出ArgumentNullException)。

  • 用戶提供一個空的csv文件位置(拋出一個ArgumentException)。

  • 用戶指定的csv文件不存在(無論您認爲合適)。

接下來,爲這些場景中的每一個寫一個測試,並確保它失敗。接下來,編寫足夠的代碼以使測試通過。這很容易讓其中的一些條件,因爲這使你的測試通過的代碼往往是最終代碼:

public class Merger { 
    public void Merge(string csvPath, string templatePath, string outputPath) { 
     if (csvPath == null) { throw new ArgumentNullException("csvPath"); } 
    } 
} 

之後,進入標準的情況:

  • 指定的CSV文件一行(合併應該被調用一次,輸出寫入預期位置)。

  • 指定的csv文件有兩行(合併應被調用兩次,輸出寫入預期位置)。

  • 輸出文件的名稱符合您的期望(無論那是什麼)。

依此類推。一旦你進入第二階段,你將開始識別你想要存根和模擬的行爲。例如,檢查一個文件是否存在 - .NET並不容易將它存根,所以你可能需要創建一個適配器接口和類,它可以讓你將程序從實際的文件系統中分離出來不要說實際的CSV文件和郵件合併模板)。還有其他的方法,但這種方法是相當標準:

public interface IFileFinder { bool FileExists(string path); } 

// Concrete implementation to use in production 
public class FileFinder: IFileFinder { 
    public bool FileExists(string path) { return File.Exists(path); } 
} 

public class Merger { 
    IFileFinder finder; 
    public Merger(IFileFinder finder) { this.finder = finder; } 
} 

在測試中,你會傳遞一個存根實現:

[Test] 
[ExpectedException(typeof(FileNotFoundException))] 
public void Fails_When_Csv_File_Does_Not_Exist() { 

    IFileFinder finder = mockery.NewMock<IFileFinder>(); 
    Merger  merger = new Merger(finder); 
    Stub.On(finder).Method("FileExists").Will(Return.Value(false)); 

    merger.Merge("csvPath", "templatePath", "outputPath"); 
} 
+1

非常好的具體例子! – Davy8 2010-12-09 15:56:56

2

爲了能夠進行單元測試,您需要將類與任何依賴關係分離,以便您可以有效地測試類本身。

要做到這一點,你需要注入任何依賴到類中。您通常會通過將實現依賴性接口的對象傳入構造函數中的類來完成此操作。

模擬框架用於創建您的依賴項的模擬實例,您的類可以在測試過程中調用該模擬實例。您定義模擬的行爲方式與您的依賴關係相同,然後在測試結束時驗證它的狀態。

我會建議玩一下Rhino mocks,並通過文檔中的例子來了解它是如何工作的。

http://ayende.com/projects/rhino-mocks.aspx

5

簡單的一般指導:

  • 你先寫單元測試。在開始 他們都失敗了。
  • 然後你將進入被測試的課程 並編寫代碼,直到每個方法都通過與 相關的測試。
  • 對於您的類型的每個公開方法 都這樣做。

通過編寫單位測試,你實際上指定的要求,但在另一種形式,易於閱讀的代碼。

從另一個角度看待它:當你收到一個新的黑盒子類和單元測試時,你應該閱讀單元測試,看看這個類是怎樣工作的。

想了解更多關於單元測試我推薦一個很好的書:Art Of Unit Testing

這裏有一對夫婦的文章鏈接在計算器上關於TDD的更多細節和例子:

+1

+1引用單元測試的藝術。這是一本很棒的書。 – Steven 2010-12-09 15:06:47