ios unit test getting stared

45
iOS Unit test getting started Liyao Chen @ KKBOX

Upload: liyao-chen

Post on 12-Aug-2015

995 views

Category:

Software


0 download

TRANSCRIPT

iOS Unit test getting started

Liyao Chen @ KKBOX

Outlines

• What is unit testing?

• Unit testing

• Why is unit testing important?

What is unit testing?

–Roy Osherove

通過調⽤用公共⽅方法產⽣生⼀一個測試的可⾒見結果

What is unit testing?

(⾦金迎 譯)

–wiki

Unit testing is a software testing method to determine whether they are fit for use.

單元測試是定義程式碼符合需求的⽅方法

What is unit testing?

–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?

Work as the developer intended?

Work as intended

你跟著師⽗父去幫別⼈人佈線安裝電燈,師⽗父三兩下就搞定了,然後請你確認有沒有裝好,請問你會怎麼做?

打開開關看看電燈有沒有跟著亮再關上開關看電燈有沒有跟著暗

Work as intended

Work as intended

1. 執⾏行模擬器2. 移動到你要測試的程式碼區塊

3. 確認程式碼如預期執⾏行

最費時

如果你要測試的程式碼在第10⾴頁呢?

Work as intended

1. 執⾏行模擬器2. 移動到你要測試的程式碼區塊

3. 確認程式碼如預期執⾏行

如果可以跳過第⼆二步呢?

<0.2 seconds

Work as intended

Unit testing

• Unit test 3A rules

• 驗證的⼿手法

• XCTest

• 優秀的單元測試

Unit test 3A Rules

• Arrange: Get the environment ready.

• Act: Call the method under test.

• Assert: Ensure that what you expected to happen, happened.

前置設定 > 動作 > 衡量結果

Unit test 3A Rules

前置設定 > 動作 > 衡量結果

關燈的房間 > 按下電燈開關 > 電燈打開(開燈的房間)

Spec: 測試房間電燈開關是否正常運作。

關燈的房間 > 按下電燈開關 > 電燈打開(開燈的房間)

驗證的⼿手法

如何程式化?

驗證的⼿手法

• 回傳值

• 狀態

• 互動

驗證的⼿手法 - 驗證回傳值#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

#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

驗證的⼿手法 - 驗證狀態

#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

驗證的⼿手法 - 驗證互動

#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

驗證的⼿手法 - 驗證互動

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

Why is unit testing important?

Why is unit testing important? - objc.io issue 15-4

• 避免代碼惡化惡化在什麼時候發⽣生?在你修改代碼的時候

• 使重構更簡單你可以⾃自信的修改實現細節,不害怕改壞其他程式碼

• 減少了創造軟體的時間通過更快速地修改代碼,出錯時測試會告訴你哪裡錯

• 提供了可執⾏行的說明和⽂文檔 你在什麼時候更想知道軟體實際上是如何運作的?在你想修改它們的時候

Why is unit testing important? - objc.io issue 15-2

目前為止,我們的編碼庫已經縱橫 190 個文件和 18,000 行代碼,達到了 544 kB。我們測試部分的代碼現在差不多有1,200 kB,大概是被測試代碼的兩倍。

– Arne Schroppe and Daniel Eggert

Why is unit testing important?

–Zonble

SQLite 的測試⼤大約是原始碼的⼀一千倍

How you choose open source?

Why is unit testing important?

Why is unit testing important?

Star?

Why is unit testing important?

Document?

Why is unit testing important?

Tests result?

Why is unit testing important?

- (void)testBasicOnSuccess { [[[BFTask taskWithResult:@"foo"] continueWithSuccessBlock:^id(BFTask *task)

{ XCTAssertEqualObjects(@"foo", task.result); return nil; }] waitUntilFinished]; }

task.result == 傳⼊入物件

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 會標記

Trust

Why is unit testing important?

優秀的單元測試

• 時機(Timely)

• 容易理解(Easy)

• 快速(Fast)

• 隔離(Isolated)

• 可重複(Repeatable)

• ⾃自我檢驗(Self-verifying)

優秀的單元測試 I

• 容易理解(Easy)團隊中任何⼀一⼈人都能看懂、它應該第⼆二天還有意義、如果它失敗了,應該很容易發現原因是什麼,去追朔到問題所在

• 可重複(Repeatable) 每次運⾏行測試都應該產⽣生相同的結果

• 快速(Fast)測試應該能夠被經常執⾏行、在幾分鐘內完成所有單元測試

優秀的單元測試 II with TDD

• 隔離(Isolated)測試本⾝身不依賴外部因素或者其他測試的結果(獨⽴立於其他測試的運⾏行)

• 帶⾃自檢(Self-verifying) 測試應該包括斷⾔言,不需要⼈人為干預

• 時機(Timely)測試應該和產品代碼⼀一同書寫

Unit testing for me is …

Testing is spec

Testing is memoryIf you can’t remember how you die(crash) last time. How to evolute your software?

Summary

• 確保程式碼持續按照計畫執⾏行的⽅方法

• 對程式碼與修改程式碼產⽣生信⼼心

• 幫你記住曾經犯下的錯誤,並且預防再犯

QnA• 測試不是QA的⼯工作嗎?

• 寫測試會花我很多時間

• 寫測試是為了Debug嗎?

• 沒有測試我也可以寫出⼀一樣的程式碼,那為什麼需要測試?

• SDK升級的⼩小故事

• 哪些地⽅方⼀一定要測?

We are hiring!

@ KKBOX

待續

• 測試為什麼重要

• 如何寫出好的單元測試

• 測試驅動開發(TDD)

• ⾏行為驅動開發(BDD)

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

Other links

• Sample codehttps://github.com/gliyao/LCUnitTestsExample

• Notehttps://www.evernote.com/l/AA-0a-6p00NHiLVAY_OTIDJ64J6jMPiU2zM