使用 SenTestCase 為 Continuous Integration 之路更踏實
"Testing is not closely integrated with development. This prevents you from measuring the progress of development- you can't tell when something starts working or when something stops working. Using JUnit you can cheaply and incrementally build a test suite that will help you measure your progress, spot unintended side effects, and focus your development efforts." - Test Infected:Programmers Love Writing Tests. by Kent Beck, Erich Gamma.
導入 Unit Test 開發可以用最便宜又累積性的建置測試套件,如此一來可以幫忙幫助評估進度,未發掘的潛在 side effects,改此程式動到另外邊功能的狀況,而且可以用對力氣更專注在開發。
在上篇 天使與魔鬼對於 Unit Test 的影響 有對單元測試做了些看法分類,而當最近選擇導入 Test Driven Development 測試導向開發,再次找到了投資的好處了。要投資在很怕會異動的程式、最底層不希望會出錯的程式、每天測試保持在最佳狀態。換言之,使用者介面 User Interface 以外,都是很好的投資點。對應到 iPhone App Project 開發,以 Model-View-Control 架構來看,Model 是最可以撰寫的地方。而根據過去經驗,這邊是最少修改被挑剔批評,同時也是邏輯重要陣地。
SenTestingKit framework,是 Objective-C testing framework 建立在 SUnit 之上,Kent Beck 的 Smallltalk unit testing framework。同時在 Java 的 JUnit 也看得到,而且這是發佈出來 Open Source 的。對應到 Apple 在 XCode 2.1 之後都已經有包含這個套件可以使用。
以一個已經寫好跟 Server Side 的 API 互動的 MyEventListModel 為例,他的功能是透過 HTTP Request 來取得最新活動的清單,解析資料內容 JSON or XML,轉換為內部 NSObject 的 Data Object。在撰寫 MyEventListModelTest 是繼承 SenTestCase。
MyEventListModelTest.m 部分,在 setUp 這個地方可以為每一個 Test Case 開始前做些準備,而 tearDown 部份是為每一個 Test Case 結束後做個收尾。
透過執行被測試的程式,將執行過後的程式套上 Assertion 假定預期要得到的結果,而在第二個參數加上如果該測試沒有過的話要顯示的文字。如此當整批測試起來發生某幾個沒過關的,可以第一時間知道為什麼。
Unit Test 是為了 Continuous Integration 打下基礎的投資,寫的目的希望可以在後面更繁忙的開發之路,能確保之前投資過的地方,有個測試保障,如此不論是開發新的功能,或是修改某些功能,都能知道會不會受到影響。我剛剛跑了一個開發中的 iPhone App 專案,結果得到:
MyProjectTests.octest(Tests)' finished at 2011-11-12 15:58:21 +0000.
Executed 39 tests, with 0 failures (0 unexpected) in 37.810 (37.827) seconds
Test Suite 'All tests' finished at 2011-11-12 15:58:21 +0000.
Program ended with exit code: 0
你的開發中專案程式今天測試了嗎?
導入 Unit Test 開發可以用最便宜又累積性的建置測試套件,如此一來可以幫忙幫助評估進度,未發掘的潛在 side effects,改此程式動到另外邊功能的狀況,而且可以用對力氣更專注在開發。
在上篇 天使與魔鬼對於 Unit Test 的影響 有對單元測試做了些看法分類,而當最近選擇導入 Test Driven Development 測試導向開發,再次找到了投資的好處了。要投資在很怕會異動的程式、最底層不希望會出錯的程式、每天測試保持在最佳狀態。換言之,使用者介面 User Interface 以外,都是很好的投資點。對應到 iPhone App Project 開發,以 Model-View-Control 架構來看,Model 是最可以撰寫的地方。而根據過去經驗,這邊是最少修改被挑剔批評,同時也是邏輯重要陣地。
SenTestingKit framework,是 Objective-C testing framework 建立在 SUnit 之上,Kent Beck 的 Smallltalk unit testing framework。同時在 Java 的 JUnit 也看得到,而且這是發佈出來 Open Source 的。對應到 Apple 在 XCode 2.1 之後都已經有包含這個套件可以使用。
以一個已經寫好跟 Server Side 的 API 互動的 MyEventListModel 為例,他的功能是透過 HTTP Request 來取得最新活動的清單,解析資料內容 JSON or XML,轉換為內部 NSObject 的 Data Object。在撰寫 MyEventListModelTest 是繼承 SenTestCase。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@interface MyEventListModelTest : SenTestCase | |
@property (nonatomic, retain) MyEventListModel *eventListModel; | |
// 測試熱門活動清單 | |
- (void)testHot; | |
// 測試 API 搭配 limit 和 offset 可以查詢某些筆數資料 | |
- (void)testLimitOffset; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@implementation MyEventListTests | |
@synthesize eventListModel = _eventListModel; | |
- (void)setUp { | |
[super setUp]; | |
_eventListModel = [[MyEventListModel alloc] init]; | |
self.eventListModel.delegate = self; | |
self.eventListModel.isSendSync = YES; | |
} | |
- (void)tearDown { | |
TT_RELEASE_SAFELY(_eventListModel); | |
[super tearDown]; | |
} | |
- (void)testHot { | |
// … 開始呼叫 API 取得資料 | |
[self.eventListModel load]; | |
// … 開始判斷回傳結果 | |
STAssertTrue([self.eventListModel.status.code isEqualToString: | |
@"0"], @"code = 0", nil); | |
STAssertTrue([self.eventListModel.status.message isEqualToString: | |
@"Success"], @"Success", nil); | |
STAssertTrue([self.eventListModel.events count] > 0, | |
@"Must have event", nil); | |
for (MyEvent *event in self.eventListModel.events) { | |
STAssertTrue(IsStringWithAnyText(event.eventId), | |
@"Must have eventId", nil); | |
} | |
} |
Unit Test 是為了 Continuous Integration 打下基礎的投資,寫的目的希望可以在後面更繁忙的開發之路,能確保之前投資過的地方,有個測試保障,如此不論是開發新的功能,或是修改某些功能,都能知道會不會受到影響。我剛剛跑了一個開發中的 iPhone App 專案,結果得到:
MyProjectTests.octest(Tests)' finished at 2011-11-12 15:58:21 +0000.
Executed 39 tests, with 0 failures (0 unexpected) in 37.810 (37.827) seconds
Test Suite 'All tests' finished at 2011-11-12 15:58:21 +0000.
Program ended with exit code: 0
你的開發中專案程式今天測試了嗎?
Comments
Post a Comment