Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

iOS Unit test getting stared

3,395 views

Published on

Summary
- 確保程式碼持續按照計畫執行的方法
- 對程式碼與修改程式碼產生信心
- 幫你記住曾經犯下的錯誤,並且預防再犯

Published in: Software
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

iOS Unit test getting stared

  1. 1. iOS Unit test getting started Liyao Chen @ KKBOX
  2. 2. Outlines • What is unit testing? • Unit testing • Why is unit testing important?
  3. 3. What is unit testing?
  4. 4. –Roy Osherove 通過調⽤用公共⽅方法產⽣生⼀一個測試的可⾒見結果 What is unit testing? (⾦金迎 譯)
  5. 5. –wiki Unit testing is a software testing method to determine whether they are fit for use. 單元測試是定義程式碼符合需求的⽅方法 What is unit testing?
  6. 6. –Stephen Ritchie “performing intention checking” The unit tests check that the program works and continues to work as the developer intended or planned for it to work. 單元測試檢驗程式碼是否按照開發者的計畫執⾏行 What is unit testing?
  7. 7. Work as the developer intended?
  8. 8. Work as intended 你跟著師⽗父去幫別⼈人佈線安裝電燈,師⽗父三兩下 就搞定了,然後請你確認有沒有裝好,請問你會 怎麼做? 打開開關看看電燈有沒有跟著亮
 再關上開關看電燈有沒有跟著暗
  9. 9. Work as intended
  10. 10. Work as intended 1. 執⾏行模擬器
 2. 移動到你要測試的程式碼區塊 3. 確認程式碼如預期執⾏行 最費時 如果你要測試的程式碼在第10⾴頁呢?
  11. 11. Work as intended 1. 執⾏行模擬器
 2. 移動到你要測試的程式碼區塊 3. 確認程式碼如預期執⾏行 如果可以跳過第⼆二步呢?
  12. 12. <0.2 seconds Work as intended
  13. 13. Unit testing • Unit test 3A rules • 驗證的⼿手法 • XCTest • 優秀的單元測試
  14. 14. Unit test 3A Rules • Arrange: Get the environment ready. • Act: Call the method under test. • Assert: Ensure that what you expected to happen, happened. 前置設定 > 動作 > 衡量結果
  15. 15. Unit test 3A Rules 前置設定 > 動作 > 衡量結果 關燈的房間 > 按下電燈開關 > 電燈打開(開燈的房間) Spec: 測試房間電燈開關是否正常運作。
  16. 16. 關燈的房間 > 按下電燈開關 > 電燈打開(開燈的房間) 驗證的⼿手法 如何程式化?
  17. 17. 驗證的⼿手法 • 回傳值 • 狀態 • 互動
  18. 18. 驗證的⼿手法 - 驗證回傳值 #import "LCCalculator.h" @interface LCCalculatorTests : XCTestCase @end @implementation LCCalculatorTests // 驗證回傳值 - (void)testSum { //Arrange LCCalculator *calculator = [[LCCalculator alloc] init]; NSNumber *a = @10; NSNumber *b = @5; //Act NSNumber *result = [calculator sumWithA:a andB:b]; //Assert XCTAssertTrue([result isEqualToNumber:@15]); } @end
  19. 19. #import "LCRoom.h" @interface LCRoomTests : XCTestCase @end @implementation LCRoomTests #pragma mark - openLight // 驗證狀態 // 關燈的房間 > 按下電燈開關 > 電燈打開 (開燈的房間) - (void)testOpenLightWhenLightOff { //Arrange - 關燈的房間 LCRoom *room = [[LCRoom alloc] initWithLight:NO]; //Act - 按下電燈開關 [room openLight]; //Assert - 電燈打開 (開燈的房間) XCTAssertTrue(room.isLight); } @end 驗證的⼿手法 - 驗證狀態
  20. 20. #import "LCRoom.h" #import "LCHouse.h" @interface LCHouseTests : XCTestCase @end @implementation LCHouseTests //驗證互動 - (void)testTurnOffHouseLight { //Arrange LCRoom *roomA = [[LCRoom alloc] initWithLight:YES]; LCRoom *roomB = [[LCRoom alloc] initWithLight:YES]; LCHouse *house = [[LCHouse alloc] initWithRooms:@[roomA, roomB]]; //Act [house turnOffHouseLight]; //Assert XCTAssertFalse(roomA.isLight); XCTAssertFalse(roomB.isLight); } @end 驗證的⼿手法 - 驗證互動
  21. 21. #import "DummyUITableViewDataSource.h" @interface LCTableViewTests : XCTestCase @end @implementation LCTableViewTests //驗證互動 - (void)testExample { //Arrange DummyUITableViewDataSource *dataSource = [[DummyUITableViewDataSource alloc] init]; UITableView *tableView = [[UITableView alloc] init]; tableView.dataSource = dataSource; //Act [tableView reloadData]; //Assert NSInteger rowCount = [tableView numberOfRowsInSection:0]; XCTAssertEqual(rowCount, 40); } @end 驗證的⼿手法 - 驗證互動
  22. 22. XCTest #import <UIKit/UIKit.h> #import <XCTest/XCTest.h> @interface ValueTests : XCTestCase @end @implementation ValueTests - (void)testExample { XCTAssertNil(nil); XCTAssertNotNil(@"123"); XCTAssertTrue(YES, @"Pass"); XCTAssertFalse(NO, @"Pass"); XCTAssertEqual(10, 10, @"Pass"); XCTAssertTrue([@"123" isEqualToString:@"123"]); XCTAssertGreaterThan(10, 5); XCTAssertLessThan(5, 7); } @end Tests 後綴 test 前綴 Assertion
  23. 23. Why is unit testing important?
  24. 24. Why is unit testing important? - objc.io issue 15-4 • 避免代碼惡化
 惡化在什麼時候發⽣生?在你修改代碼的時候 • 使重構更簡單
 你可以⾃自信的修改實現細節,不害怕改壞其他程式碼 • 減少了創造軟體的時間
 通過更快速地修改代碼,出錯時測試會告訴你哪裡錯 • 提供了可執⾏行的說明和⽂文檔 
 你在什麼時候更想知道軟體實際上是如何運作的?在你想 修改它們的時候
  25. 25. Why is unit testing important? - objc.io issue 15-2 目前為止,我們的編碼庫已經縱橫 190 個文件和 18,000 行代碼,達到了 544 kB。我們測試部分的代碼 現在差不多有1,200 kB,大概是被測試代碼的兩倍。 – Arne Schroppe and Daniel Eggert
  26. 26. Why is unit testing important? –Zonble SQLite 的測試⼤大約是原始碼的⼀一千倍
  27. 27. How you choose open source? Why is unit testing important?
  28. 28. Why is unit testing important? Star?
  29. 29. Why is unit testing important? Document?
  30. 30. Why is unit testing important? Tests result?
  31. 31. Why is unit testing important? - (void)testBasicOnSuccess 
 { [[[BFTask taskWithResult:@"foo"] continueWithSuccessBlock:^id(BFTask *task) { XCTAssertEqualObjects(@"foo", task.result); return nil; }] waitUntilFinished]; } task.result == 傳⼊入物件
  32. 32. Why is unit testing important? - (void)testBasicOnSuccessWithToken 
 { BFCancellationTokenSource *cts = [BFCancellationTokenSource cancellationTokenSource]; BFTask *task = [BFTask taskWithDelay:100]; task = [task continueWithExecutor:[BFExecutor immediateExecutor] successBlock:^id(BFTask *task) { XCTFail(@"Success block should not be triggered"); return nil; } cancellationToken:cts.token]; [cts cancel]; [task waitUntilFinished]; XCTAssertTrue(task.isCancelled); } 可以取消⽽而且 isCancelled 會標記
  33. 33. Trust Why is unit testing important?
  34. 34. 優秀的單元測試 • 時機(Timely) • 容易理解(Easy) • 快速(Fast) • 隔離(Isolated) • 可重複(Repeatable) • ⾃自我檢驗(Self-verifying)
  35. 35. 優秀的單元測試 I • 容易理解(Easy)
 團隊中任何⼀一⼈人都能看懂、它應該第⼆二天還有意義、如果它失敗了,應該很 容易發現原因是什麼,去追朔到問題所在 • 可重複(Repeatable) 
 每次運⾏行測試都應該產⽣生相同的結果 • 快速(Fast)
 測試應該能夠被經常執⾏行、在幾分鐘內完成所有單元測試
  36. 36. 優秀的單元測試 II with TDD • 隔離(Isolated)
 測試本⾝身不依賴外部因素或者其他測試的結果(獨⽴立於其他測試的運⾏行) • 帶⾃自檢(Self-verifying)
 測試應該包括斷⾔言,不需要⼈人為干預 • 時機(Timely)
 測試應該和產品代碼⼀一同書寫
  37. 37. Unit testing for me is …
  38. 38. Testing is spec
  39. 39. Testing is memory If you can’t remember how you die(crash) last time. How to evolute your software?
  40. 40. Summary • 確保程式碼持續按照計畫執⾏行的⽅方法 • 對程式碼與修改程式碼產⽣生信⼼心 • 幫你記住曾經犯下的錯誤,並且預防再犯
  41. 41. QnA • 測試不是QA的⼯工作嗎? • 寫測試會花我很多時間 • 寫測試是為了Debug嗎? • 沒有測試我也可以寫出⼀一樣的程式碼,那為什麼需要 測試? • SDK升級的⼩小故事 • 哪些地⽅方⼀一定要測?
  42. 42. We are hiring! @ KKBOX
  43. 43. 待續 • 測試為什麼重要 • 如何寫出好的單元測試 • 測試驅動開發(TDD) • ⾏行為驅動開發(BDD)
  44. 44. Reference • http://kevjenkins.blogspot.tw • http://www.ithome.com.tw/news/90500 • http://www.objc.io/issues/15-testing/ • http://blog.miniasp.com/post/2010/02/21/The- Art-of-Unit-Testing-with-Roy-Osherove- Notes.aspx
  45. 45. Other links • Sample code
 https://github.com/gliyao/LCUnitTestsExample • Note
 https://www.evernote.com/l/ AA-0a-6p00NHiLVAY_OTIDJ64J6jMPiU2zM

×