版權聲明

所有的部落格文章都可以在右邊[blog文章原始檔案]下載最原始的文字檔案,並依你高興使用 docutil 工具轉換成任何對應的格式方便離線閱覽,除了集結成書販賣歡迎任意取用,引用

TDD in XCode (Objective-C)

TDD in XCode (Objective-C)

What is TDD?

TDD (Test Driven Develop) 近期因為敏捷式開發火紅也受到相當的重視, TDD 用三條規則就可以說明其實踐和理念。

  1. You are not allowed to write any production code unless it is to make a failing unit test pass.
  2. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
  3. You are not allowed to write any more production code than is sufficient to pass the one failing unit test.

大意就是,寫最基本的測試->通過測試->重構->進行下一個測試,其實我還滿認同 TDD 的理念的,先求穩在求好。 一開始我也覺得如此開發阿很浪費時間,其實自己實際在一些案子上面實踐後,發現其實並不會尤其開發功能越多, 越複雜的反而比較節省時間。


主要原因大概是習慣 TDD 之後開發過程大腦會比較自然的專注於單一功能上面,遇到問題也比不用TDD開發可以 在更短的時間裡將問題可能的範圍縮小,長時間開發對於比較久遠的 code 使用上也比較不易出錯。 在認真處理 程式重構後程式碼更清楚,功能的聚集力更強,程式間的耦合性也會降低。

TDD in XCode 準備工作

  1. 首先建立一個新的 Target (Project->New Target),並選擇 Cocoa 下的 unit test bundle. 隨便命一個你覺得有意義的名字,比如 unittest。
http://s3.amazonaws.com/ember/PvWUTbl53oJ97QyZKHG01pput3xIYhSO_m.png
  1. 修改 target 的設定,在xcode點選剛剛建立的 target 按 command+i 或是工具列上面的 info 按鈕帶出設定頁面。

    選擇target

    http://s3.amazonaws.com/ember/RB8GwLyCFXKcjBLojTqCDR06f15sqjbR_m.png

    設定頁面

http://s3.amazonaws.com/ember/doaRvR3KwpvxD73fUAop8K5ZT3zNZQWf_m.png
  1. 在 Link Other Link 中將 Cocoa 換成 Fundation , 因為視覺方面的 unittest 其實 目前這個測試架框沒法支援,所以不需要連結這麼肥的 cocoa framework。 然後再 user-defined 將 GCC_PREFIX_HEADER 欄位整個刪除。

    http://s3.amazonaws.com/ember/dEyYPmghgqzoFwmKlzkOcYxNss0v95yE_m.png
  2. 開始撰寫測試程式,由於測試條件會隨專案發展越來越大,這邊建議可以利用 Xcode 提供的一些 組織管理功能來管理,您可以增加一個新的 Group 裡面放所有的測試程式。

  3. 接下來建立 Test Case Class,[Add New File] -> Cocoa Class -> Objective-C Test Case Class 請參考下圖,名稱建議取一個有意義的比如 MainControllerTest.m 。

    http://s3.amazonaws.com/ember/JW3ZGhmbmiRZ97PkHZ1hTYFRvn4hU2iU_m.png
  4. 建立的 Class 請加到步驟一建立的 Test Target 裡。這邊我拿掉 also create xx.h 因為我不喜歡 太多零碎的檔案。

    http://s3.amazonaws.com/ember/laOfY3LtLhccOIk7ZSrxGhT63XKPzQji_m.png

    注意一點如果你和我一樣不點選 also create xxx.h 要自行在 test case class 的 .m 檔中將宣告部分加進去(請參考下面程式片段自行修改)。

    // Test case class 需繼承自 SenTestCase,所以要引入對應的 HeadFile
    #import <SenTestingKit/SenTestingKit.h>
    // 引入要測試的 Class 宣告 (真正實踐功能的 Code)
    #import "TAppDelegate.h"
    
    @interface AppTest : SenTestCase
    {
      // 宣告部分。
    }
    @end
    

這時候可以先Build並觀察結果了,Build前請先確定 Target 是選 test target。

http://s3.amazonaws.com/ember/3tVKBuKxAuBLNustvv0SrL4lqSFFPS1R_m.png

請注意 Build 結果除了編譯錯誤外還有一個 shell run error,這是 cocoa unittest 自動 啟動的 command line script 用來執行所有的測試條件。

Test Example

建立好 Test case class 後要寫測試程式碼很簡單,只要method名字用test開頭即可,雖然沒有硬性規定, 但是這些內容是測試碼的 methods 最好不要一個 method 就測試很多很多不同的功能。

example:

@implementation AppTest
- (void)testAdd
{
    Calculator *calculator = [[Calculator alloc] init];
    int expected = 9;
    int result = [calculator add:3 to:6];
    STAssertEquals(expected,result,@"We expect %d, but it was %d",expected,result);
}
@end

第一次應該會測試失敗,應該會看到類似的畫面:

http://s3.amazonaws.com/ember/HB5LoOvSqSUTCk9h86apGBtyG5S3qnX6_m.png

修正錯誤,繼續下一個測試,如此循環就是 TDD 最基本的開發流程。

同其他的 test framework cocoa unittest 也有針對測試時候必要的資源管理有特定的 初始和結束的 methods。

- (void) setUp
{
     // Init code
}

- (void) tearDown
{
     // Release code
}

Refer to: http://blog.jayway.com/2010/01/15/test-driven-development-in-xcode/

沒有留言:

Related Posts with Thumbnails