測試驅動開發之可執行檔文檔

來源:互聯網
上載者:User

TDD已經發展多年,然而卻仍未能普遍成為日常開發的實踐之一,很多人在嘗試使用TDD時遭遇了困難,並對TDD心存疑惑。我並非TDD方面的權威或專家,但希望能將我的經驗和感想記錄下來,希望能對某些仍對TDD有所困惑的人有所協助,同時也希望能夠聽到不同的聲音,共同交流與討論。

 本教程不是工具的使用教程,也不是TDD入門知識普及教程,因此這裡不會告訴你TDD是什麼,TDD的工具如何使用。關於TDD的基本概念和工具的使用,已經有很多文檔可以參考,請自行學習。

 

測試驅動開發之可執行檔文檔

"編寫單元測試更多是一種設計行為文檔行為而不是單純的驗證行為。編寫單元測試縮短了很多反饋周期;其中至少縮短了功能的驗證周期。”   - Robert C. Martin

對於TDD的驗證功能(測試功能)大家都不陌生,也很好理解,可是對於TDD的文檔功能卻有很多人不瞭解。

項目中的文檔可以分很多種,例如需求文檔、設計文檔、使用者手冊、維護手冊等等。這些文檔可能是列印出來的,也可能以電子形式存在,而其內容可能是文字、圖表、圖形甚至是視頻。今天我們討論的文檔偏向於設計文檔,其他文檔並不涉及。

設計文檔一般有兩種用途,在程式開發出來之前,設計文檔用於指導編碼,而在編碼之後,設計文檔用於協助理解代碼。MSDN中的類庫參考也是一種設計文檔(同時也是協助文檔),它描述了類庫的使用方式和它們之間的聯絡,更重要的是其中有很多的例子可以幫我們理解如何使用這些類庫。那麼這和TDD有什麼關係呢?

我們先看一個例子

Code
public void twelve_inches_should_equal_to_one_foot()
{
Inch twelveInches = new Inch(12);
Foot oneFoot = new Foot(1);

Assert.AreEqual(twelveInches, oneFoot);
}

public void one_foot_plus_two_inches_should_equal_to_fourteen_inches()
{
Foot oneFoot = new Foot(1);
Inch twoInches = new Inch(2);
Inch fourteenInches = new Inch(14);

Assert.AreEqual(oneFoot.Plus(twoInches), fourteenInches);
}

public void twelve_inches_should_equal_to_one_foot()
{
int twelve = 12;
int one = 1;
Assert.AreEqual(new Inch(twelve), new Foot(one));
}

可以看到,TDD的測試案例實際上也是一個個使用這些類和函數的例子,測試函數的名稱就是測試所要表達的意圖,測試代碼就是實現這種意圖的方式。你可以從測試代碼中得到以下資訊:這個函數或類能幹什麼,約束條件是什麼,何時會引發異常,合理的輸入範圍是什麼,對應於輸入的輸出是什麼,如何調用這些API等等。

那麼為什麼要用TDD來執行文檔的功能呢?這就要說說文檔的一些問題了。

首先要說的是,文檔有很多的好處,這已經被廣泛認可了,否則我也不用在這裡說TDD的文檔功能了;其次文檔不一定非要是文字或圖表的形式,我們的最終目的是要用文檔來表達一些資訊,一些從代碼裡無法得到或不容易得到的資訊。傳統文檔如UML圖,或是用NDoc之類的軟體產生的API參考已經可以傳達這些資訊了,但是他們也有一些缺點:

1. 文檔與代碼不同步。通常代碼永遠都是最新的,而文檔則會有一個滯後期,維護文檔和代碼的同步成本非常高,許多項目會因為這個成本而導致文檔和代碼不同步。這時候文檔根本描述不了代碼,而文檔的意義也已經不存在了,要麼你從文檔中得到錯誤資訊,要麼用更多的時間去看代碼。如果使用TDD的方式寫代碼,由於實現每個函數之前必須要先寫相關的測試,保證了每個(public)函數都有文檔說明,同時當函數行為發生變化時,也必須先添加或修改測試,保證了測試這份文檔永遠是最新的。

2. 項目進行中沒有API文檔。API的說明文檔很多都是在程式碼完成後才寫成的,項目進行時,經常會出現某個人誤用另一個人寫的函數而導致bug的情況。使用TDD的方式,可以通過閱讀測試代碼來學習如何使用其他人寫的類或方法,比直接讀實現代碼更有效,可以很好的避免誤用的情況,有助於提高品質。

3. 寫文檔成本太高,沒時間寫,程式員不喜歡或不擅長寫文檔。TDD作為一個開發實踐有多種功能,文檔只是其中之一,同樣時間內用TDD可以獲得更多的收益,降低了文檔的成本。同時,測試也是用程式員熟悉的語言寫成,程式員比較容易掌握。

那是不是只要TDD就好了,不需要其他的文檔了呢?當然不是,TDD的文檔功能有很多好處,但是什麼東西都不是萬能的,我們還是需要配合多用形式的文檔來達到我們的目的。具體實踐時可根據對TDD的掌握程度,項目對文檔的要求,團隊對文檔的要求,來決定用什麼形式來撰寫文檔。

使用TDD的文檔功能時需要非常注意代碼的可讀性,這是它能否執行文檔功能的一個重要條件。

再來一個UAT測試的例子

Code
 [Test]
 public void should_not_create_publication_in_offline_mode_when_click_no()
 {
    using (ribbonTestUtility = new RibbonTestUtility())
    {
        ribbonTestUtility.StartWordInOfflineMode();
        ribbonTestUtility.ClickCreatePublication();

        OfflineWarningDialogModel warningDialogModel = ribbonTestUtility.GetOfflineWarningDialog();
        warningDialogModel.ClickNo();

        EftAssert.IsWindowNotExists(ribbonTestUtility.EftApplication,
                                            RibbonElementName.SETUP_WIZZARD_WINDOW_TITLE);
    }
 }


[Test]
        public void should_not_create_publication_in_offline_mode_when_click_no()
        {
            using (ribbonTestUtility = new RibbonTestUtility())
            {
                ribbonTestUtility.StartWordInOfflineMode();
                ribbonTestUtility.ClickCreatePublication();
                OfflineWarningDialogModel warningDialogModel = ribbonTestUtility.GetOfflineWarningDialog();
                warningDialogModel.ClickNo();

                EftAssert.IsWindowNotExists(ribbonTestUtility.EftApplication,
                                            RibbonElementName.SETUP_WIZZARD_WINDOW_TITLE);
            }
        }

 

用底線來分割單詞雖然不符合C#的命名規範,可是提高了可讀性,因為Pascal Case的方法名很長時可讀性會很差,畢竟命名規範是為了提高可讀性而設計的。方法名應該表示該測試的意圖,並符合英語文法,可以當成普通的英語句子閱讀。

我的一個同事曾經參加過一個項目,在這個項目中有很多領域詞彙,很難用英語表達出來,即使表達出來看的人也很難理解。考慮到溝通成本以及項目中並沒有老外存在的情況,他們決定使用中文TDD,用中文給測試案例命名。雖然用中文寫代碼並不是很好的實踐,但在這個項目中確實能夠解決問題,可以說應變的非常好。也希望大家能夠認清技術和實踐的本質和目的,靈活運用,避免盲從。

總結

TDD除了可以驗證功能外,還具有文檔功能。它永遠保持最新,可以表達程式意圖,並且可以編譯執行,是可執行檔文檔。但是決不能用TDD文檔代替所有文檔,需要在項目中進行權衡。在實踐中,代碼可讀性影響著TDD文檔功能的效果,表達不了意圖的代碼是無法執行文檔功能的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.